Potresti dirmi l'ora, per favore? [chiuso]


55

Sai che le API dell'orologio / ora della tua lingua sono rotte e non sono affatto affidabili.

Pertanto, non è consentito utilizzare alcuna API integrata per accedere all'ora / data del sistema.

Ma sai anche che la capacità della tua lingua di eseguire la matematica della data e di conservare un valore di data / ora in una variabile sono corrette.

Scrivi un programma che stampa la data / ora corrente senza chiamare alcuna API data / ora / orologio. Ad esempio DateTime.Now, GetDate()e funzioni simili non sono consentite.

Vince la risposta con la maggior parte dei voti.

In caso di pareggio, vince la risposta con maggiore precisione (ovvero accurata fino a secondi, quindi millisecondi, quindi microsecondi e così via).


2
In altre parole, parlare con un time server?
Peter Taylor,

3
Si, puoi farlo. Una possibile soluzione.
microbian

3
Domanda piuttosto non specifica. Immagino che il maggior numero di voti verrà raccolto da una risposta simile print(input("Please enter the current time")).
Howard

7
I miei soldi sono su "Carica REPL per un'altra lingua e chiama la sua API del tempo non interrotta".
Jonathan Van Matre,

2
@swich anche questo non è permesso. Perché la tua risposta diventerà inaffidabile.
microbian

Risposte:


121

Giava

Quasi tutte le soluzioni attuali presuppongono che il computer locale / remoto non stia mentendo su un orario corrente (crederesti anche sul T-600?).
Il calcolo del punto chiave nel tempo è la fiducia in una natura pura .
Questa app per Android chiede all'utente di scattare foto del cielo e prevede l'ora attuale con una precisione eccezionale:

public void onActivityResult(int requestCode, int resultCode, Intent data) 
{
   if (resultCode == RESULT_OK) 
   {
      Uri selectedImageUri = data.getData();
      this.imageView.setImageURI(selectedImageUri);

      TimeGuesser guesser = new TimeGuesser(this);
      String result = guesser.guessTimeFromImage(selectedImageUri);
      this.textView.setText(result);   
   }
}

public class TimeGuesser {

    private Context context;
    public TimeGuesser(Context context)
    {
        super();
        this.context = context;
    }

    public String guessTimeFromImage(Uri uri) {
        Bitmap bitmap = null;
        try {
            bitmap = MediaStore.Images.Media.getBitmap(this.context.getContentResolver(), uri);
        } catch (IOException e) {
            return "There is no sky. Everyone's going to die";
        }

        float brightness = getBrightness(bitmap);

        if (brightness < 90.0)
        {
            return "It's sooo late";
        } else {
            return "It's sooo early";
        }
    }

    private float getBrightness(Bitmap bitmap)
    {
        float R, G, B;
        R = G = B = 0.0f;
        int pixelColor;
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        int size = width * height;

        for (int x = 0; x < width; ++x) {
            for (int y = 0; y < height; ++y) {
                pixelColor = bitmap.getPixel(x, y);
                R += Color.red(pixelColor);
                G += Color.green(pixelColor);
                B += Color.blue(pixelColor);
            }
        }

        R /= size;
        G /= size;
        B /= size;

        float brightness =  (0.2126f*R ) + (0.7152f*G) + (0.0722f*B);
        return brightness;
    }
}

risultati:

inserisci qui la descrizione dell'immagine


inserisci qui la descrizione dell'immagine


49
+1 per "There is no sky. Everyone's going to die": D
Maniglia della porta

6
"Tutti moriranno - o il tuo dito è sopra la telecamera. Praticamente la stessa cosa."
corsiKa

Specificare Java
user1886419

3
Questo è sicuramente il mio preferito, spero solo che non arrivi a un pareggio ...
Dryden Long

21
E le eclissi? È probabile che causino un problema tanto quanto lo sono durante lo sviluppo di Java!
ciao

64

Rubino

Siamo onesti: il tempo cambia solo quando qualcosa è pubblicato su stackoverflow.com ;)

Lo script estrae il tempo dell'etichetta "XYs ago" nella domanda più in alto.

require 'net/http'
source = Net::HTTP.get('stackoverflow.com', '/')

puts source.match(/span title=\"(.*)\" class=\"relativetime/)[1]

Produzione:

2014-03-10 18:40:05Z

2
Accurato solo al secondo ... e al secondo che SO trasmette la sua adorazione vergognosa
David Wilkins

3
IL <CENTRO> NON PUO 'TENERE VENUTO
Maniglia della porta

@Doorknob Ho davvero bisogno di stampare quel post e appenderlo al mio muro.
wchargin,

30

bash

Come questo? (richiede wgete grep)

wget -qO- 'http://www.wolframalpha.com/input/?i=current+time'|grep ' am \| pm '

L'output che ho ricevuto pochi minuti fa:

                    Why am I seeing this message? 
  context.jsonArray.popups.pod_0200.push( {"stringified": "6:08:38 pm GMT\/BST  |  Monday, March 10, 2014","mInput": "","mOutput": "", "popLinks": {} });

O questo? (richiede wgete eog)

wget http://c.xkcd.com/redirect/comic/now
eog ./now
rm ./now

Uscita che ottengo ora: (Immagine di xkcd )

mappa del mondo con fuso orario http://c.xkcd.com/redirect/comic/now


@tbodt Non sono sicuro se vedrai questo commento. La modifica non è valida perché http://c.xkcd.com/redirect/comic/nowfornisce un'immagine mentre http://xkcd.com/nowfornisce una pagina Web.
ace_HongKongIndipendenza

9
Mi sono appena reso conto che il fumetto visualizzato cambia in base all'ora del giorno. È fantastico
RJFalconer,

2
È un peccato che il fumetto non includa l'ora legale. (Ad esempio, mentre scrivo questo, gli Stati Uniti orientali sono solo quattro ore indietro rispetto al Regno Unito, non i normali cinque mostrati dal fumetto.) Più significativamente, gli emisferi nord e sud possono spostarsi di due ore fuori sincrono.
David Richerby,

16
Dico +1 a xkcd per non aver osservato l'ora legale e spero che il resto del mondo segua l'esempio.
hoosierEE

29

SH / coreutils

touch . && stat . -c %z

Emette la data in un formato un po 'non standard: anche
YYYY-MM-DD hh:mm:ss.nanoseconds +timezone
se immagino che potrebbe dipendere dalle impostazioni locali.


1
Non funziona Dice permesso negato :)
devnull

5
@devnull il tuo filesystem è terribilmente rotto. cd $(mktemp -d)
Risolvilo

Meh, il tempo di dir è impostato usando una funzione di libreria.
Navin,

@Navin Non è impostato. L'inode della directory è appena aperto per la scrittura e il kernel aggiorna il suo mtime. Non c'è nessun esplicito set mtime to thissyscall da nessuna parte
mniip

@mniip Welll, va bene. Sento ancora che touchè una funzione / comando di libreria poiché ha l'effetto collaterale desiderato.
Navin,

25

PHP

Sfruttare il fatto che uniqid()restituisce un ID in base al tempo.

$u=hexdec(substr(uniqid(),0,8));

$y=floor($u/31536000);
$u-=$y*31536000;
$y+=1970;

$d=floor($u/86400);
$u-=$d*86400;

$h=floor($u/3600);
$u-=$h*3600;

$m=floor($u/60);

$s=$u-$m*60;

echo 'Year='.$y.' Days='.$d.' Hours='.$h.' Minutes='.$m.' Seconds='.$s;

Durante la mia prova, è tornato: Year=2014 Days=79 Hours=18 Minutes=9 Seconds=49.
Non so se posso usare dateper formattare correttamente, quindi l'ho convertito manualmente.


2
Sono sicuro che questo sta piegando le regole ... uniqidfa ancora parte della tua lingua ... Ma ricevi comunque un +1
mniip

Perché ? sì, uniqidusa l'API di tempo di basso livello ma anche quando richiedi tempo da un server esterno ci sarà una chiamata di basso livello all'API di tempo da qualche parte ...
Michael M.

1
Non sto parlando di chiamate API tempo qui. Sto dicendo che fa ancora parte della lingua.
mniip,

2
@mniip sì, ma uniqid()era rotto prima ancora che questa domanda fosse posta. solo le API orologio / ora sono interrotte in questa domanda
Riking

23

DNS

Diffidiamo solo della nostra macchina? Se è così, questo conta?

ssh $othermachine date

Se ciò non conta, l'estrazione del tempo dall'aggiornamento DNS fa sicuramente:

dig stackexchange.com | grep WHEN

23

bash

Giusto per essere sempre assolutamente precisi e corretti:

echo "Now"

o motivante:

echo "Now, do something useful today"

10
toady, sostantivo, toadies plurale. Un adulatore lusinghiero; sycophant. ( Fonte )
ace_HongKongIndipendenza

3
No absolutely precise, eseguire il comando richiederà ancora un po 'di tempo da ragazzino.
user80551

2
@ user80551 Ed è quello che ti sbagli, ora è sempre perfettamente preciso. Se guardi il tempo dell'orologio cambia prima che l'immagine raggiunga l'occhio. Ma ora, ora è sempre adesso.
Master117,

10
@ user80551 echo "Then"funziona per tale requisito.
Taemyr,

2
-Che diavolo sto guardando? Quando succede questo nel programma? -Adesso! Stai guardando Ora signore, qualunque cosa stia succedendo ora nel programma sta succedendo adesso. -Cosa aggiungere allora? -È passato -Quando? -Solo ora
ilmale

20

arricciatura: precisa per qualunque sia la frequenza del ping

curl -s time.nist.gov:13

Bello, ma è in UTC, non dovrebbe essere in ora locale?
Orione,

24
@orion Non siamo locali nell'universo?
Pureferret,

Questo è uno dei 2 server predefiniti utilizzati da Windows per sincronizzare l'ora.
Ismael Miguel,

@IsmaelMiguel è anche usato da molti sistemi non standard ..
David Wilkins

Sto solo dicendo. Non sto dicendo che è l'unico posto dove viene utilizzato. Sto solo raccontando un fatto.
Ismael Miguel,

14

Pitone

Sei sicuro di non sapere che ore sono?!? Ecco un promemoria:

print "It's Adventure Time!"

6
È l'ora del clobberin :)
orion, l'

13

Python 2

Quindi, l'orologio è corretto ma l'API del tempo è corretta, giusto? Perché non controllare un timestamp del filesystem non elaborato. Invece di creare un file di test, utilizziamo semplicemente il nostro timestamp di accesso poiché lo script deve essere letto per essere eseguito (anche se è stato compilato). Accurato al secondo. *

import os
h, m = divmod(os.stat('t.py').st_atime % 86400, 3600)
print h+1, m // 60, m % 60

Questo dovrebbe essere salvato ed eseguito come t.py. In alternativa, ottenere il nome dello script in fase di esecuzione coninspect.getfile(inspect.currentframe())

Nota * Occasionalmente accurato al secondo precedente .


Dovremmo controllare t.pyco t.pyoinvece?
Kyle Kelley

1
Buona idea, ma questi non esistono se non si importa questo file come modulo (o li si crea manualmente). Comunque ho controllato e python (2.7.2 su OS X) toccherà il .pyfile anche se .pycè presente il corrispondente . Quindi funziona sempre correttamente.
alexis

Notato e votato. Ben fatto.
Kyle Kelley,

10

Rubino

HTTP, ma solo usando i metadati di risposta.

require 'uri'
require 'net/http'

def get_now
  uri = URI.parse("http://google.com")
  http = Net::HTTP.new(uri.host, uri.port)
  request = Net::HTTP::Get.new(uri.request_uri)
  rsp = http.request(request)
  rsp['date']
end

9

ps

Non sai psdire l'ora? Può!

sleep 1&  ps -o lstart -p $!

Il processo viene avviato in background e psindica l'ora di inizio del processo. Da quando il processo è iniziato in background, l'ora di inizio del processo è praticamente la stessa ora di adesso.

Inoltre, il vantaggio è che l'ora è ottenuta nel fuso orario locale. E non hai nemmeno bisogno di una connessione Internet!


7

VBA

perché non dovrei.

Public Function DateTime() As String
Dim myNTPsvr As String
Dim dattime As String
Dim oHTTP As Object

myNTPsvr = "time.windows.com"
Set oHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
oHTTP.Open "GET", "http://" & myNTPsvr & "/", False
oHTTP.Send

DateTime = oHTTP.GetResponseHeader("Date")

Set oHTTP = Nothing
End Function

usa ?DateTimeper usare, o se lo metti in Excel, =DateTime()funzionerà come una formula.
La data / ora viene restituita in GMT - Lascio come esercizio inutile per convertirlo da una stringa all'ora locale


6

Bash + last+ head+cut

Preciso al secondo. lastutilizza il file di registro/var/log/wtmp

$ last -RF reboot | head -n1 | cut -c50-73
Tue Mar 11 09:38:53 2014
$ 

EDIT: aggiunto headper limitare a una sola riga.

EDIT: Funziona su Linux Mint 13 Cinnamon 64-bit ma sembra che questo dipenda dalla tua distribuzione. sysvinit-utils(che fornisce last) la versione viene 2.88dsf-13.10ubuntu11.1 lastletta /var/log/wtmp(nel mio caso) quindi i risultati dipendono da quel file di registro. Vedi i commenti qui sotto.

EDIT: Apparentemente questo dipende dal tempo di attività del sistema, quindi puoi vedere la prova qui http://imgur.com/pqGGPmE


Ciò restituisce una riga vuota qui. E non sono sicuro che qualcosa di rilevante possa essere estratto da lì, come lastdice l' uomo "Il pseudo utente riavvia il login ogni volta che il sistema viene riavviato." (E nemmeno quello sembra essere corretto qui: pastebin.com/ArUaBcuY )
manatwork

@manatwork imgur.com/SeJX9RA In realtà, -Fstampa i tempi completi di accesso e disconnessione . Poiché l'utente corrente è ancora connesso, l'ora di disconnessione è l'ora corrente. Questo è su Linux Mint 13 cannella a 64 bit. Potrebbe dipendere dalle impostazioni locali ma ne dubito.
user80551

@manatwork Funziona anche qui
user80551

2
Rotto sull'arco (systemd). Restituisce "ancora in esecuzione".
orion,

5
In realtà, "ancora in esecuzione" è almeno filosoficamente un momento giusto.
orion,

5

Pitone

Ottenere una precisione in nanosecondi sarebbe complicato a meno che il tempo di ritorno non fosse basato su quando il programma termina l'esecuzione, non quando si avvia. Con questo in mente ha più senso calcolare il tempo in base al termine di un programma. Ciò significa che dovremmo controllare quando un programma si interrompe per ottenere una precisione maggiore.

import subprocess

def what_day_is_it(): return int(subprocess.check_output(["date", "+%dd"]))[:-2];

current_day = next_day = what_day_is_it # It's a bash call, 
while not current_day - next_day:
  next_day = what_day_is_it()
print "It's midnight."
print "Probably."

Si noti che ciò presuppone o mentre l'orologio in pitone è borked, l'orologio bash non lo è o che l'orologio bash almeno sa che giorno è. In caso contrario, possiamo invece utilizzare questo:

def what_year_is_it(): return int(subprocess.check_output(["date", "+%yy"]))[:-2];

Potrebbe essere leggermente più lento, però. Non l'ho provato.


5

BrainFuck

>+++++++[-<++++++++>]<---.>+++++[-<+++++>]<++.---.>++++++++[-<-------->]<---.

Produzione:

5PM

Penso che sia l'ora di Denver al momento della stesura. La spiegazione per l'algoritmo qui da questo video di Alan Jackson .


xkcd.com/221 ma per tempo, vedo.
val

@val Entrambi condividono la proprietà che sono diventati costanti in fase di esecuzione, ma la canzone è corretta. Sono le 17:00 da qualche parte. La cosa XKCD accade molto poiché i nuovi sviluppatori pensano che il calcolo del tempo di espansione delle macro faccia risparmiare tempo.
Sylwester,

Ma fa davvero risparmiare tempo! Nel risultato eseguibile effettivamente.
val

5

Rubino

`date`

Non utilizza l'API orologio / ora della lingua.


Cosa fa esattamente?
Hosch250,

1
Esegue il comando date nella shell e restituisce l'output.
nero

4

Mi è piaciuta l'idea "leggere da un time server". Tuttavia, ha migliorato la sua formattazione e aggiunto alcune città per divertimento.

PHP

$page = file_get_contents("http://www.timeapi.org/utc/now");
echo "In London: ".date("H:i:s - jS F, Y", strtotime($page))."<br>";
echo "In Rome: ".date("H:i:s - jS F, Y", strtotime($page)+3600)."<br>";
echo "In Athens: ".date("H:i:s - jS F, Y", strtotime($page)+7200)."<br>";


4

C / WinAPI

Questo presuppone che le mie chiamate API per interrogare l'orologio siano interrotte, ma il sistema stesso può funzionare correttamente con l'ora.

// NO ERROR CHECKING - that's left as an exercise for the reader
TCHAR tmpfilename[MAX_PATH];
TCHAR tmpfilepath[MAX_PATH];

// get some information to create a temporary file
DWORD dwRes = GetTempPath(MAX_PATH, tmpfilepath);
UINT uiRes  = GetTempFileName(tmpfilepath, TEXT("golftime"), 0, tmpfilename);

// create the file
HANDLE hTempFile = CreateFile(tmpfilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

// read the creation time of the file. accuracy is to, uhm... 10ms on NTFS?
FILETIME created;
GetFileTime(hTempFile, &created, NULL, NULL);

// convert the filetime to a system time (in UTC)
SYSTEMTIME systime;
FileTimeToSystemTime(&created, &systime);

std::cout << "Time is " <<
    systime.wHour << ":" << systime.wMinute << ":" << systime.wSecond << "." << systime.wMilliseconds << "\n";

// close the file and delete
CloseHandle(hTempFile);
DeleteFile(tmpfilename);

L'idea è di creare un file temporaneo e leggere i tempi di creazione, che su NTFS ritengo accurati fino a 10ms. Nota che la formattazione dell'output è incerta, ma è puramente pigro.

Uscita sulla mia macchina proprio ora: Time is 10:39:45.790


1
// NO ERROR CHECKING - that's left as an exercise for the reader- Meglio non vederlo nel codice di produzione
wchargin,

4

Lotto

@echo off
echo.>>%0
for /f "tokens=2,3 skip=4" %%a in ('dir /TW %0') do echo %%a %%b & goto :EOF

Scrive una riga vuota nel file batch (stesso), quindi controlla l'ultimo tempo di scrittura del file.

H:\uprof>GetTime.bat
09:28 AM

H:\uprof>GetTime.bat
09:29 AM

3

HTML, CSS e Javascript / jQuery

Ok, quindi so che questo non è tecnicamente un programma e probabilmente non rientra nei criteri, ma tra poche ore questo sarà l'orologio più preciso al mondo!

CSS

@font-face {
    font-family:"DSDIGI";
    src:url("http://fontsforweb.com/public/fonts/1091/DSDIGI.eot") format("eot"),
    url("http://fontsforweb.com/public/fonts/1091/DSDIGI.ttf") format("truetype");
    font-weight:normal;
    font-style:normal;
}
#backer {
    background-image: url('http://i.imgur.com/w3W5TPd.jpg');
    width: 450px;
    height: 354px;
    color: red;
    font-family: 'DSDIGI';
}
#backer p {
    width: 100%;
    display: block;
    line-height: 325px;
    font-size: 60px;
}

HTML

<div id="backer">
    <p>
        BEER<span id="fade">:</span>30
    </p>
</div>

jQuery

function start() {
    $('#fade').fadeOut(function() {
        $('#fade').fadeIn();
    });
    setTimeout(start, 1000);
}
start();

All'inizio stavo per fare un while(true)ciclo, ma poi mi sono ricordato che non volevo mandare in crash alcun browser ...

Eccone un violino in azione: http://jsfiddle.net/E7Egu/

inserisci qui la descrizione dell'immagine


4
flare_points ++;
scunliffe,

Adoro il fatto che 2 anni dopo qualcuno viene e vota in negativo questo ... lol
Dryden Long,

3

Emacs Lisp

La cosa di google è stata fatta ma non in emacs!

(url-retrieve "http://www.google.com/search?q=time" (lambda(l)            
        (search-forward-regexp "[0-9]?[0-9]:[0-9][0-9][ap]m")
        (print (buffer-substring (point) (1+ (search-backward ">"))))))

2

node.js / Javascript

var fs = require('fs'),
    util = require('util');

var date = null, time = null;

fs.readFile('/sys/class/rtc/rtc0/date', 'UTF-8', function(err, d) {
    date = d.trim();
    if(time)
        done();
})

fs.readFile('/sys/class/rtc/rtc0/time', 'UTF-8', function(err, t) {
    time = t.trim();
    if(date)
        done();
});

function done() {
    console.log(util.format('%sT%sZ', date, time));
}

1
ho perso alcune dependance lì. Che sapore ha Linux?
Non che Charles

1
Cosa manca, la directory / sys / class / rtc / rct0? Sono su Arch Linux.
Chris

1
sì, questo è ciò che non c'è su tutti i sistemi * nix, tanto meno tutti i sistemi!
Non che Charles

1

JavaScript

new Date(performance.timing.navigationStart+performance.now())+''

Dato che l'API clock / time non funziona, utilizzo Performance API per ottenere l'ora. Quindi Dateviene utilizzato solo per analizzarlo in stringa.


2
Non sono sicuro che si adatti alle regole :)
Oriol

Quell'API ha un supporto terribile.
Ismael Miguel,

1

PHP:

 $n=PHP_SHLIB_SUFFIX=='dll'?strtotime(str_replace(PHP_EOL,' ',`date /t&time /t`).' GMT'):`date +%s`;

Questo leggerà l'ora di sistema dall'interfaccia della riga di comando disponibile.

L'operatore backtick è usato per fare proprio questo: eseguire un comando.

Un altro modo sarebbe:

$_SERVER['REQUEST_TIME'];

Che contiene l' ora corrente in cui è stato chiamato lo script.


Non dipende ancora dal tuo sistema per tempo?
Maurice,

2
Prima riga della domanda : "Sai che le API dell'orologio / ora della tua lingua sono interrotte e non sono affatto affidabili". Penso che questo si spieghi.
Ismael Miguel,

1

bash

export PS1="(\t) $PS1"

Evita un po 'le regole, ma non chiama mai una funzione temporale. Tuttavia, verrà visualizzata l'ora corrente all'uscita, e ogni volta che premi Invio dopo.


1

C #

Questo metodo super preciso funzionerà, a condizione che eseguirai il programma a 0: 00: 00,0000

using System;
using System.Threading;

namespace ConsoleApplication1 {
  class Program {
    private static volatile int s_Hour;
    private static volatile int s_Minute;
    private static volatile int s_Second;
    private static volatile int s_Millisecond;

    class Looper {
      public int Length { get; set; }
      public Action Update { get; set; }
    }

    static void Loop(object args) {
      var looper = (Looper)args;
      while (true) {
        Thread.Sleep(looper.Length);
        looper.Update.Invoke();
      }
    }

    static void Main(string[] args) {
      var starter = new ParameterizedThreadStart(Loop);
      new Thread(starter).Start(new Looper { Length = 100, Update = () => { s_Millisecond = (s_Millisecond + 100) % 1000; } });
      new Thread(starter).Start(new Looper { Length = 1000, Update = () => { s_Second = (s_Second + 1) % 60; } });
      new Thread(starter).Start(new Looper { Length = 60 * 1000, Update = () => { s_Minute = (s_Minute + 1) % 60; } });
      new Thread(starter).Start(new Looper { Length = 60 * 60 * 1000, Update = () => { s_Hour++; } });

      Console.Out.WriteLine(@"Press e to exit, enter to write current time...");
      while (true) {
        string input = Console.In.ReadLine();
        if (input == "e") {
          Environment.Exit(0);
          return;
        }
        Console.Out.WriteLine("{0:00}:{1:00}:{2:00},{3}", s_Hour, s_Minute, s_Second, s_Millisecond);
      }
    }
  }
}

Thread.Sleep garantisce solo che un thread dormirà per un minimo di quanto specificato tra parentesi. Può facoltativamente rimanere a dormire molto più a lungo.
Bryan Boettcher,

1

Linux, la maggior parte delle shell, su hardware con un RTC:

echo `cat /sys/class/rtc/rtc0/{date,time} | tr "\n" " "`

Questo non chiama un'API data / ora?
Hosch250,

Non capisco il bit della subshell dell'eco. Presumibilmente vuoi normalizzare la spaziatura delle parole, ma se è così, perché il trbit? Forse vuoi solo paste -d' ' /sys/class/rtc/rtc0/{date,time}?
Kojiro,

E se lo provassi sul Raspberry PI, che non ha un RTC ?!
George

@kojiro Sì, e la tua strada è più pulita.
trav

1

Giava

Sappiamo tutti che l'API Java Date / Time è inutilizzabile e non funzionante. Quindi, ecco una correzione che non utilizza (almeno direttamente) nessuna delle API esistenti. Supporta anche i secondi bisestili! :) L'output è in UTC.

import java.lang.reflect.Field;
import java.net.HttpCookie;
import java.util.*;

public class FixedTimeAPI4Java {

    private static final List<Integer> MONTHS_WITH_30_DAYS = Arrays.asList(4, 6, 9, 11);
    private static final List<Integer> YEARS_WITH_LEAP_SECOND_IN_DECEMBER = Arrays.asList(1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1987, 1989, 1990, 1995, 1998, 2005, 2008);
    private static final List<Integer> YEARS_WITH_LEAP_SECOND_IN_JUNE =  Arrays.asList(1972, 1981, 1982, 1983, 1985, 1992, 1993, 1994, 1997, 2012);

    /**
    * Returns the UTC time, at the time of method invocation, with millisecond
    * precision, in format <code>yyyy-MM-dd HH:mm:ss.SSS</code>.
    */
    public String getTime() throws Exception {

        // The cookie is only used for accessing current system time
        HttpCookie cookie = new HttpCookie("Offline", "Cookie");
        Field created = HttpCookie.class.getDeclaredField("whenCreated");
        created.setAccessible(true);

        long millisecondsSinceEpoch = created.getLong(cookie);        
        long fullSecondsSinceEpoch = millisecondsSinceEpoch / 1000L; 

        int year = 1970, month = 1, dayOfMonth = 1, hour = 0, minute = 0, second = 0,
            millisecond = (int)(millisecondsSinceEpoch - (fullSecondsSinceEpoch * 1000L));

        ticks: 
        for (;; year++) {
            for (month = 1; month <= 12; month++) {
                for (dayOfMonth = 1; dayOfMonth <= daysInMonth(month, year); dayOfMonth++) {
                    for (hour = 0; hour < 24; hour++) {
                        for (minute = 0; minute < 60; minute++) {
                            for (second = 0; second < secondsInMinute(minute, hour, dayOfMonth, month, year); second++, fullSecondsSinceEpoch--) {
                                if (fullSecondsSinceEpoch == 0) {
                                    break ticks;
                                }
                            }
                        }
                    }
                }
            }
        }
        return String.format("%04d-%02d-%02d %02d:%02d:%02d.%03d", year, month,
            dayOfMonth, hour, minute, second, millisecond);
    }

    /**
     * Returns the seconds in the given minute of the given hour/day/month/year,
     * taking into account leap seconds that can be added to the last minute of
     * June or December.
     */
    private static int secondsInMinute(int minute, int hour, int day, int month, int year) {
        return (minute == 59 && hour == 23 && ((day == 30 && month == 6) || (day == 31 && month == 12))) 
                ? 60 + leapSecondsInMonth( month, year) 
                : 60;
    }

    /**
     * Returns the number of days in the given month of the given year.
     */
    private static int daysInMonth(int month, int year) {
        return month == 2 ? isLeapYear(year) ? 29 : 28
                : MONTHS_WITH_30_DAYS.contains(month) ? 30
                    : 31;
    }

    /** 
     * Returns whether the given year is a leap year or not. 
     * A leap year is every 4th year, but not if the year is divisible by 100, unless if it's divisible by 400.
     */
    private static boolean isLeapYear(int year) {
        return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? true : false;
    }

    /** 
     * Returns the number of leap seconds that were added to UTC time at the end of the given month and year.
     * Leap seconds are added (by the decison of International Earth Rotation Service / Paris Observatory)
     * in order to keep UTC within 0.9 seconds of international atomic time (TAI).
     * <p>TODO: implement parser for updated list at http://www.ietf.org/timezones/data/leap-seconds.list :)
     */
    private static int leapSecondsInMonth(int month, int year) {        
        return (year < 1972 || year > 2012) ? 0
                : (month == 6 && YEARS_WITH_LEAP_SECOND_IN_JUNE.contains(year)) ? 1
                    : (month == 12 && YEARS_WITH_LEAP_SECOND_IN_DECEMBER.contains(year)) ? 1
                        : 0;
    }

    public final static void main(String[] args) throws Exception {
        System.out.println(new FixedTimeAPI4Java().getTime());        
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.