Ein Bruchjahr


8

Mein PPCG-Urlaub ist vorbei: D.

Intro

Bruchzeit ist the year + (the value (minute of year) / number of minutes in the year).

Beispielberechnung

Sie sollten davon ausgehen, dass der Februar immer 28 Tage hat und das Jahr immer 365 Tage lang ist.

Angenommen, wir möchten die Zeit 17:34 3rd March 2013in Bruchzeit umrechnen . Zunächst finden Sie heraus, wie viele Minuten 2013 waren: 525600 Minuten . Nennen wir das x.

Als nächstes möchten Sie herausfinden, wie viele Minuten seit Anfang 2013 vergangen sind. Ein paar schnelle Berechnungen zeigen Ihnen, dass die Antwort 88894 Minuten lautet:

Seit Jahresbeginn sind 61 Tage vergangen, was 1440 (Anzahl der Minuten pro Tag) 87840 Minuten entspricht. In 17 Stunden sind 1020 Minuten (17 * 60). Jetzt können wir 87840, 1020 und 34 Minuten hinzufügen, was 88894 Minuten entspricht.

Nennen wir das y.

Schließlich dividieren Sie ydurch xund addieren das Jahr, was zu 2013.16912(auf 5 Dezimalstellen) führt.

Eingang

Datum und Uhrzeit werden als einzelne Zeichenfolge angegeben. Die Zeichenfolge hat das folgende Format:

YYYY-MM-DD hh:mm 

Die Zeit wird immer im 24-Stunden-Format sein und das Jahr wird immer im Bereich von 1900 bis einschließlich 2050 liegen.

Beispiele

Input:  2016-08-06 23:48
Output: 2016.59723

Input:  2013-03-03 17:34
Output: 2013.16912

Input:  1914-11-11 11:11
Output: 1914.86155

Wenn Sie sich für das Kopfgeld entscheiden, rufen Sie mich entweder in den Kommentaren oder im neunzehnten Byte an .

Herausforderung

Berechnen Sie das angegebene Datum und die angegebene Uhrzeit als Bruchjahr.

Geben Sie die gesamte Ausgabe auf fünf Dezimalstellen ein (Sie können beliebig runden: Bodenbelag, Decke oder echte Rundung). Der kürzeste Code gewinnt.

Kopfgeld

Ich biete eine Prämie von 100 Wiederholungen für das kürzeste Programm an, das auch das Datum im Bruchjahresformat akzeptiert und die Uhrzeit im YYYY-MM-DD hh:mmFormat zurückgibt . Im Wesentlichen muss Ihr Programm (oder Ihre Funktion) folgendermaßen handeln:

f('1914-11-11 11:11') => 1914.86155
f('1914.86155')       => 1914-11-11 11:11
  1. t-clausen.dk - 154 Bytes
  2. Neil - 183 Bytes

Bestenliste


Vielleicht würde die Verwendung von Datum und Uhrzeit als Eingabe Testfälle und eine einfachere Überprüfung ermöglichen?
Luis Mendo

Ich bin ein bisschen verwirrt, ob dies die angegebenen Schaltjahre berücksichtigt For this, assume February has 28 days and the year is 365 days long., aber auch... using the Gregorian calendar.
Destructible Lemon

@DestructibleWatermelon Nein, Schaltjahre werden nicht berücksichtigt
Beta Decay

Können wir mehr als fünf Dezimalstellen angeben?
Zitrone

@ DestructibleWatermelon No
Beta Decay

Antworten:


1

TSQL, 63 Bytes

Dies ist eine kürzere Version als meine ursprüngliche Antwort, da meine erste Antwort die Berechnung für das Schaltjahr beinhaltete.

DECLARE @ DATETIME ='2016-08-06 23:48'

PRINT LEFT(YEAR(@)+DATEDIFF(mi,0,STUFF(@,1,4,1900))/525600.,10)

Geige

Das folgende SQL kann beide Eingabetypen verarbeiten

TSQL, 154 Bytes

DECLARE @ VARCHAR(16) ='1914-11-11 11:11'--can be replaced with '1914.86155'

PRINT IIF(isdate(@)=1,LEFT(YEAR(@)+DATEDIFF(mi,0,STUFF(@,1,4,1900))/525600.,10),LEFT(@,4)+RIGHT(CONVERT(CHAR(16),DATEADD(mi,1*RIGHT(@,5)*5.256,0),20),12))

Kombinierte Geige 1

Kombinierte Geige 2


5

JavaScript (ES6), 84 Byte

f=
s=>(Date.parse(1970+s.slice(4).replace(/ /,'T')+'Z')/31536e6+parseInt(s)).toFixed(5)
;
<input placeholder=Input oninput=o.value=f(this.value)><input placeholder=Output id=o>

Unter der Annahme, dass keine Schaltjahre oder Sommerzeit erforderlich sind, ersetze ich das Jahr durch 1970, wodurch Date.parseder Zeitversatz in Millisekunden, von dem es 315360000001970 (oder in der Tat jedes andere Nicht-Schaltjahr) gab, direkt zurückgegeben wird . Dann muss ich nur noch das Jahr addieren und auf 5 Dezimalstellen runden. Bearbeiten: Bidirektionale Konvertierung in 183 178 Bytes:

f=
s=>/:/.test(s,m=31536e6)?(Date.parse(1970+s.slice(4).replace(/ /,'T')+'Z')/m+parseInt(s)).toFixed(5):s.slice(0,4)+new Date(s.slice(4)*m+3e4).toJSON().slice(4,16).replace(/T/,' ')
;
<input placeholder=Input oninput=o.value=f(this.value)><input placeholder=Output id=o>

Angenommen, Zeichenfolgen, die ein :Zeitformat enthalten, werden wie oben behandelt, andernfalls wird das Jahr entfernt, in Millisekunden konvertiert, eine halbe Minute für Rundungszwecke hinzugefügt, 1970 in ein Datum konvertiert, Monat, Tag, Stunde und Minute extrahiert und das vorangestellt ursprüngliches Jahr.


@ βετѧΛєҫαγ Ja, sist das Argument für die Funktion.
Neil

Gibt dies nicht eine ungültige Ausgabe, da die Herausforderung ausdrücklich verlangt, dass der Februar nur 28 Tage und insgesamt 365 Tage pro Jahr hat?
AdmBorkBork

@TimmyD manchmal hat der Februar 29 Tage. Nehmen wir an, es bedeutet nicht, dass es nicht erlaubt ist, Schaltjahre korrekt zu behandeln
t-clausen.dk

@ t-clausen.dk Sorry, ich meinte, dass Schaltjahre nicht behandelt werden sollten
Beta Decay

@ βετѧΛєҫαγ Verwendet jetzt weder Schaltjahre noch Sommerzeit und hat auch eine reversible Version. Ist das zufriedenstellend?
Neil

2

Matlab, 132 115 Bytes

 d=input('');m=cumsum([-1 '# #"#"##"#"'-4]);year(d)+fix((((m(month(d))+day(d))*24+hour(d))*60+minute(d))/5.256)/10^5

Runden gegen 0.

Hmmm ... das ist ziemlich lang.
Das nutzt einige eingebaute, aber nicht die wirklich hilfreichen - wegen der Schaltjahre.

Das direkte Parsen des Strings ergibt 2 weitere Byte-Lösungen:

d=sscanf(input(''),'%d%[- :]');m=cumsum([-1 '# #"#"##"#"'-4]);d(1)+fix((((m(d(3))+d(5))*24+d(7))*60+d(9))/5.256)/10^5

Neuere Matlab-Versionen haben wahrscheinlich eine bessere Split-Funktion, aber ich verwende 2012a.

Einige Bytes wurden dank @Luis Mendo gespeichert


Sie können das Array mit definieren [-1 '# #"#"##"#"'-4], um einige Bytes zu speichern. Sind yearusw. Standardfunktionen? Wenn Sie eine Toolbox verwenden, sollten Sie diese im Titel angeben, z. B. "Matlab with Financial Toolbox"
Luis Mendo

@ LuisMendo Ich bin mit der #Notation nicht vertraut und bin ihr noch nie begegnet. Wo kann ich mehr darüber lesen (schnelle Google-Suche hat nicht geholfen)? Ich denke, die yearusw. sind Standardfunktionen, aber ich weiß nicht, ob sie sich außerhalb der Toolbox (Dokumente) gleich verhalten .
Pajonk

Es ist keine spezielle Notation. Es ist nur eine Zeichenfolge mit Zeichen, die die entsprechenden ASCII-Codes haben, um die erforderlichen Zahlen zu erzeugen. Was die Funktionen angeht, wusste ich nicht, danke für die Klarstellung. Matlab 15b scheint sie nicht zu haben
Luis Mendo

Oh, das ist klug.
Pajonk

1

PowerShell v3 +, 131 Byte

$t=date $args[0];$a=1440*!!(date "2-29-$($t.year)");"{0:F5}"-f((($t.DayOfYear-1)*1440+$t.TimeOfDay.TotalMinutes-$a)/525600+$t.Year)

Nimmt Eingaben auf $args[0]und konvertiert sie mit Get-Date, um sie im .NET- [datetime]Format zu speichern $t. Berechnet, ob der 29. Februar existiert, und legt fest, $adass der Minutenwert dieses Datums (falls vorhanden) abgezogen wird.

Dann wir die Verwendung -fOrmat Operators mit einer festen String Spezifikation von 5 Dezimalstellen durch die Berechnung auszuführen. Verwendet integrierte Funktionen, um die .DayOfYearund die .TotalMinutesEingabe zu berechnen , zu subtrahieren, $awenn es sich um ein Schaltjahr handelt, durch die 525600Gesamtzahl der Minuten zu dividieren und die Eingabe zu addieren .Year.

Wird sich (wörtlich) bei STDERR beschweren, wenn der 29. Februar nicht existiert (siehe Beispiele unten), aber da STDERR standardmäßig ignoriert wird, machen wir uns darüber keine Sorgen. Beachten Sie außerdem, dass PowerShell standardmäßig die Rundung von Bankern durchführt.

Beispiele

PS C:\Tools\Scripts\golfing> .\fractional-year.ps1 '2016-08-06 23:48'
2016.59724

PS C:\Tools\Scripts\golfing> .\fractional-year.ps1 '2013-03-03 17:34'
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "2-29-2013" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At C:\Tools\Scripts\golfing\fractional-year.ps1:7 char:36
+   $t=date $args[0];$a=1440*!!(date "2-29-$($t.year)");"{0:F5}"-f((($t.DayOfYear- ...
+                                    ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Date], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand

2013.16913

PS C:\Tools\Scripts\golfing> .\fractional-year.ps1 '1914-11-11 11:11'
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "2-29-1914" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At C:\Tools\Scripts\golfing\fractional-year.ps1:7 char:36
+   $t=date $args[0];$a=1440*!!(date "2-29-$($t.year)");"{0:F5}"-f((($t.DayOfYear- ...
+                                    ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Date], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand

1914.86155

Alternativ mit Schaltjahren 119 Bytes

"{0:F5}"-f((($t=date $args[0]).DayOfYear-1+$t.TimeOfDay.TotalMinutes/1440)/(date "12-31-$($t.year)").DayOfYear+$t.Year)

Wenn wir den Kalendereinstellungen folgen, können wir ein Dutzend Bytes sparen, da wir $aim obigen Originalcode nicht berücksichtigen müssen. Dies ermöglicht es uns, $tin den Ausdruck selbst zu wechseln , und wir werden den .DayOfYearfür den 31. Dezember explizit berechnen . Ansonsten folgt die gleiche Methodik.


0

Python 3, 163 173 Bytes

mehr Bytes aufgrund des Ausgabeformats

verwendet keine eingebauten Datumsangaben wie die Java-Antwort.

def s(x):z=x[5:10].split("-");v=x[10:].split(":");return int(x[:4])+(sum(([-1,31,28]+[31,30,31,30,31]*2)[:int(z[0])],int(z[1]))*1440+int(v[0])*60+int(v[1]))/525600

etwas besser lesbar

def s(x):
    date=x[5:10].split("-");time=x[10:].split(":")
    return int(x[:4])+(sum(([-1,31,28]+[31,30,31,30,31]*2)[:int(date[0])],int(date[1]))*1440+int(time[0])*60+int(time[1]))/525600

0

Perl 6 ,  107 105  102 Bytes

{$/=.comb(/\d+/);($0+(sum(|flat(-1,31,28,(31,30,31,30,31)xx 2)[^$1],$2)*1440+$3*60+$4)/525600).fmt: '%.5f'}
{$/=.comb(/\d+/);fmt $0+(sum(|flat(-1,31,28,(31,30,31,30,31)xx 2)[^$1],$2)*1440+$3*60+$4)/525600: '%.5f'}

{$/=.comb(/\d+/);fmt $0+(flat($2-1,31,28,(31,30,31,30,31)xx 2)[^$1].sum*1440+$3*60+$4)/525600: '%.5f'}
{$/=.comb(/\d+/);round $0+(flat($2-1,31,28,(31,30,31,30,31)xx 2)[^$1].sum*1440+$3*60+$4)/525600,.1⁵}

Erläuterung:

{
  $/ = .comb(/\d+/); # grab a list of only the digits
  # 「$0」 is short for 「$/[0]」

  fmt

    $0 # year
    +
    (
      flat(
        $2 -1,                     #    days
        31,28,(31,30,31,30,31)xx 2 # -+ months
      )[^$1].sum * 1440            # /
      + $3 * 60                    #    hours
      + $4                         #    minutes
    )
    /
    525600

  : '%.5f' # the 「:」 is used here as 「fmt」 is a method not a subroutine
}

Prüfung:

#! /usr/bin/env perl6
use v6.c;
use Test;

# returns Str
my &fractional-year-a = {$/=.comb(/\d+/);fmt $0+(sum(flat($2-1,31,28,(31,30,31,30,31)xx 2)[^$1])*1440+$3*60+$4)/525600: '%.5f'}
# returns Rat
my &fractional-year-b = {$/=.comb(/\d+/);round $0+(sum(flat($2-1,31,28,(31,30,31,30,31)xx 2)[^$1])*1440+$3*60+$4)/525600,.1⁵}

my @tests = (
  '2016-08-06 23:48' => 2016.59723,
  '2013-03-03 17:34' => 2013.16912,
  '1914-11-11 11:11' => 1914.86155,
);

plan +@tests * 2;

for @tests -> $_ ( :key($input), :value($expected) ) {
  is-approx +fractional-year-a($input), +$expected, 1e-5, "a $input => $expected";
  is-approx +fractional-year-b($input), +$expected, 1e-5, "b $input => $expected";
}
1..6
ok 1 - a 2016-08-06 23:48 => 2016.59723
ok 2 - b 2016-08-06 23:48 => 2016.59723
ok 3 - a 2013-03-03 17:34 => 2013.16912
ok 4 - b 2013-03-03 17:34 => 2013.16912
ok 5 - a 1914-11-11 11:11 => 1914.86155
ok 6 - b 1914-11-11 11:11 => 1914.86155
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.