Emette la stringa della data ISO8601 da secondi e nanosecondi
Uno dei motivi per cui ISO8601 è il miglior formato di stringa della data è che puoi semplicemente aggiungere la precisione che desideri. Dati 2 numeri interi che rappresentano secondi e nanosecondi trascorsi da allora 1970-01-01T00:00:00, restituisci una stringa ISO8601 come descritto di seguito.
Produzione:
Il formato di output standard senza fuso orario ha questo aspetto:
1970-01-01T00:00:00.000001
La data è codificata come "anno, mese, giorno" con 4,2,2 cifre rispettivamente, separate da un "-". L'ora del giorno è codificata come "ora, minuti, secondi" con 2,2,2 cifre rispettivamente. Quindi, facoltativamente, può seguire un punto con esattamente 6 cifre di precisione, che codifica i microsecondi trascorsi dopo la data specificata + (tempo in ore + minuti + secondi) da allora. Viene aggiunto solo se non è uguale a 000000. Vedere gli esempi di seguito
Sì, ci è permesso aggiungere 6 cifre (microsecondi) di precisione e teoricamente più sono semplicemente appendibili, sebbene non definite ulteriormente nello standard.
Ingresso:
Otterrai 2 numeri interi (secondi, nanosecondi). Per motivi di semplicità, costringiamoli a rientrare in 0 <= x < 10^9entrambi. Assicurati di scartare / arrotondare qualsiasi precisione oltre i microsecondi.
Esempi:
Input: 616166982 , 34699909 Output: 1989-07-11T13:29:42.034699
Input: 982773555 , 886139278 Output: 2001-02-21T16:39:15.886139
Input: 885454423 , 561869693 Output: 1998-01-22T07:33:43.561869
Input: 0 , 100000 Output: 1970-01-01T00:00:00.000100
Input: 0 , 1000 Output: 1970-01-01T00:00:00.000001
Input: 0 , 999 Output: 1970-01-01T00:00:00
Input: 999999999 , 999999999 Output: 2001-09-09T01:46:39.999999
Compito:
Fornire una funzione che accetta 2 numeri interi come descritto nella sezione Input e restituisce una stringa come descritto nella sezione Output.
Per dettagli e limitazioni per input / output, fare riferimento alle regole di input / output predefinite .
Questo è codegolf: vince la soluzione più breve in byte.
Risposte
Bash + sed, 37 , 59 , 50 byte
printf '%(%FT%T)T.%06d' $1 $[$2/1000]
printf "%(%FT%T)T.%06d" $1 ${2::-3}|sed s/\\.0*$//
Provalo online!
8 byte salvati grazie a @DigitalTrauma
Wolfram Language (Mathematica) , 91 byte
DateString[6!3068040+#2,"ISODateTime"]<>If[#>999,"."<>IntegerString[⌊#/1000⌋,10,6],""]&
Provalo online!
Mathematica supporta i millisecondi, ma non i microsecondi.
C (gcc) , 108 106 byte
Risparmiato 2 byte grazie a Ceilingcat !!!
#import<time.h>
o[9];f(s,n)long s;{strftime(o,99,"%FT%T",gmtime(&s));printf((n/=1e3)?"%s.%06d":"%s",o,n);}
Provalo online!
Inserisce secondi e nanosecondi come numeri interi e restituisce la data / ora formattata a stdout.
Perl 5 ( -p -MPOSIX+strftime -Minteger), 55 , 51 , 60 byte
Grazie a @Abigail per avermi dato l'idea di cambiare il formato di input. + 9 byte per gestire i microsecondi = 0 case.
$_=(strftime"%FT%T",gmtime$_).sprintf".%06d",<>/1e3
$_=(strftime"%FT%T",gmtime$_).sprintf".%06d",<>/1e3;s;\.0+$;
Provalo online!
Japt , 32 28 byte
Accetta l'input come una coppia di stringhe, con i nanosecondi per primi. Può salvare (almeno) 4 byte se possiamo includere 0s iniziali con i nanosecondi.
ùT9 ¯6
pU=n g)iÐV*A³ s3 ¯UÄ9
Provalo
Oppure, per "tradurlo" in JavaScript:
U=>V=>(
U=U.padStart(9,0).slice(0,6),
U.repeat(U=Math.sign(parseInt(U))).replace(/^/,new Date(V*10**3).toISOString().slice(0,U+19))
)
ùT9 ¯6\npU=n g)iÐV*A³ s3 ¯UÄ9 :Implicit input of strings U=nanoseconds & V=seconds
ù :Left pad U
T : With 0
9 : To length 9
¯6 :Slice to length 6
\n :Reassign to U
p :Repeat U
U= : Reassign to U
n : Convert to integer
g : Get sign
) :End repeat
i :Prepend
Ð : Create Date object from
V* : V multiplied by
A : 10
³ : Cubed
s3 : To ISO String
¯U : Slice to length U
Ä9 : +19
Groovy , 62 60 68 byte
f={s,n->"${java.time.Instant.ofEpochSecond(s,n|1)}"[0..25]-~/\.0+$/}
Provalo online!
Spiegazione
Il ofEpochSecond(epochSecond, nanoAdjustment)metodo Java restituisce il Instantcorrispondente ai secondi e ai nanosecondi dati (esattamente quello che vogliamo per questa sfida). I nanosecondi sono con OR bit per bit 1per garantire che non si finisca mai con esattamente 0 o 1_000_000 nanosecondi, pur mantenendo lo stesso comportamento di arrotondamento a 6 cifre.
"${...}"converte il Instantin a GStringcostituito dal Stringvalore dell'istante. La toStringrappresentazione di un Instantè in formato ISO-8601: "2011-12-03T10: 15: 30.000000001Z". Esclude automaticamente posizioni decimali extra oltre 0/3/6 cifre decimali (secondi / millisecondi / microsecondi) se le cifre rimanenti sono 0, quindi il precedente OR bit per bit.
"${value}"[0..25] restituisce i caratteri da 0 a 25 della stringa, che vanno dalla sesta cifra decimale.
-~/\.0+$/sottrae la prima istanza del pattern regex \.0+$dalla stringa risultante; vale a dire, una cifra decimale seguita da tutti zeri, seguita dalla fine della stringa. Ciò corrisponderà solo se la stringa termina con .000000e il codice è più corto di un carattere rispetto alla sottrazione '.000000'.
Groovy , 63 byte
f={s,n->sprintf('%tFT%1$tT.%06d',s*1000L,n/1E3as int)-~/\.0+$/}
Provalo online!
Un approccio Groovy diverso che utilizza stringhe di formato (ispirato ad altre risposte simili).
APL (Dyalog Unicode) 18.0, 53 byte ( SBCS )
Programma completo. Richiede nanosecondi, quindi secondi.
(¯7×0=f)↓⊃'%ISO%.ffffff'(1200⌶)20 1⎕DT⎕+1E¯6×f←⌊⎕÷1E3
Provalo online! (polyfills per ⌶e ⎕DTperché TIO usa ancora 17.1)
⎕÷1E3 dividere i nanosecondi di input per 1000
f← assegnato a f
1E¯6× moltiplicare per 0,000001
⎕+ aggiungere secondi di input a quello
20 1⎕DT convertire da UNIX time (secondi dal 1970) a Dyalog Date Number (giorni dal 1989-12-31)
'%ISO%.ffffff'(1200⌶) formato secondo ISO con precisione frazionaria a sei cifre
⊃ rivelare (perché una "stringa" è un vettore di caratteri racchiuso)
(... )↓ rilascia il seguente numero di caratteri
0=f uno se fè zero
¯7× sette dal retro in tal caso (lett. sette negativo moltiplicato per quello)
JavaScript (V8) , 83 94 ... 78 byte
s=>n=>new Date(s*1e3).toJSON(n=0|n/1e3).slice(0,20-!n)+`${n+1e6}`.slice(n?1:7)
Provalo online!
- Grazie a @Neil per il grande aiuto!
- Ho salvato altri 5 grazie a @Arnauld
Raku ,
46 byte
40 caratteri, 42 byte
{(~DateTime.new($^a+$^b divⅯ/1e6)).chop}
Provalo online!
Salvati alcuni byte utilizzando un numero non numerico (che potrebbe essere sostituito da altri simili ൲, ma ad altri piace 𐄢o 𑁥aggiungono un byte in più), che consentiva la rimozione dello spazio dopo div. L'unico trucco qui era quello di forzare l'arrotondamento verso il basso e rafforzare il DateTimeper poterlo fare .chop. Potrebbe in effetti esserci un bug qui in quanto l'implementazione di Rakudo viene arrotondata, e se lo consideriamo tale, allora può essere ulteriormente considerato
{(~DateTime.new($^a+$^b/1e9)).chop}
Che sarebbero solo 35 caratteri / byte.
Python 3.8 (pre-rilascio)
106
, 81 byte
lambda a,b:datetime.fromtimestamp(a+b//1e3/1e6).isoformat()
from datetime import*
Provalo online!
Excel, 102101 byte
=TEXT(25569+A1/86400,"yyy-mm-ddThh:mm:ss")&SUBSTITUTE(LEFT(TEXT(B1/10^9,"."&REPT(0,9)),7),".000000",)
L'input è in secondi A1e in nanosecondi B1.
Ci sono due pezzi principali in questo:
TEXT(25569+A1/86400,"yyy-mm-ddThh:mm:ss")
25569è l'equivalente numerico di 1970-01-01 in Excel che misura da 1900-01-00 come zero.
A1/86400converte i secondi in giorni.
"yyyy-mm-ddThh:mm:ss"formatta il risultato, dandoci la maggior parte dell'output desiderato.
SUBSTITUTE(LEFT(TEXT(B1/10^9,"."&REPT(0,9)),7),".000000",)
TEXT(B1/10^9,"."&REPT(0,9))converte da un numero intero di nanosecondi a un decimale di secondi.
LEFT(TEXT(~),7)fornisce il punto decimale con le prime 6 cifre.
SUBSTITUTE(LEFT(~),".000000",)rappresenta un <1.000 nanosecondi facendo cadere il risultato.
A parte: dato quanto è amichevole Excel con le date, ha senso, ma è comunque fastidioso, che siano necessari più byte da gestire .000000di quanti ne richieda 1970-01-01T00:00:00. Ho trovato approcci alternativi con meno byte ma funzionano solo se possiamo arrotondare i nanosecondi o visualizzare valori zero. Ahimè e ahimè.