596 Stimmen

Wie kann ich das aktuelle Datum und die Uhrzeit in UTC oder GMT in Java abrufen?

Wenn ich eine neue Date Objekts wird sie mit der aktuellen Zeit initialisiert, aber in der lokalen Zeitzone. Wie kann ich das aktuelle Datum und die Uhrzeit in GMT abrufen?

0 Stimmen

Ich weiß, diese Art von Themen sind völlig über diskutiert, aber ich fand die commons-lang-Paket wirklich behandelt diese gemeinsame Java-Probleme gut. commons.apache.org/lang/api-2.5/org/apache/commons/lang/time Informieren Sie sich über die verschiedenen Pakete, die sie anbieten.

0 Stimmen

Welche Ortszeit wünschen Sie und mit welcher Genauigkeit. Die meisten Zeitzonen sind relativ zur UTC definiert, mit einem festen Offset gemessen in SI Sekunden, aber die Beziehung der GMT, die auf der Sonnenbeobachtung und einer (leicht) variablen Länge der Sekunde basiert, ist komplexer. Die beiden unterscheiden sich um bis zu 0,9 Sekunden.

4 Stimmen

A Date enthält keine Zeitzone, daher ist "aber in der lokalen Zeitzone" nicht korrekt (oder bestenfalls ungenau). Siehe Alles über java.util.Date .

2voto

JohnPan Punkte 1070

So mache ich es, wenn ich es brauche ein Date-Objekt ausgeben was in der Regel der Fall ist, wenn man ein Datum in einer SQL-Datenbank speichern muss und ich es in UTC haben möchte. Ich ziehe einfach die Zeitverschiebung der lokalen Zeitzone ab.

    ZonedDateTime now = ZonedDateTime.now();
    Date nowUTC = new Date(1000 * (now.toEpochSecond() - now.getOffset().getTotalSeconds()));

--UPDATE Basils Vorschlag für eine sauberere Methode, um das gleiche Ergebnis zu erzielen, wäre

    Date nowUTC = Date.from(ZonedDateTime.now().toInstant());

ABER nachdem ich dies in einer Nicht-UTC-Java-Systemumgebung getestet habe, habe ich gesehen, dass die Ergebnisse nicht die gleichen sind. Mit dem Code von Basil ist das Datum immer noch in der lokalen Zone

0 Stimmen

Sie mischen die schreckliche Legacy-Klasse Date mit ihren Nachfolgern, den modernen java.time Klassen, die in JSR 310 definiert sind. Es besteht keine Notwendigkeit, entweder java.util.Date o java.sql.Date Klasse nie wieder. Die Funktionalität wird vollständig ersetzt durch die java.time Klassen (insbesondere Instant ではなく ZonedDateTime ). Instant.now()

1 Stimmen

Außerdem, wenn Sie wirklich eine java.util.Date Objekt, um mit altem, noch nicht aktualisiertem Code zu interagieren java.time rufen Sie einfach die praktische Konvertierungsmethoden zu den alten Klassen hinzugefügt : java.util.Date d = Date.fromInstant( myInstant ); . Wenn Sie eine ZonedDateTime können Sie eine Instant : java.util.Date.from( myZonedDateTime.toInstant() ) . Die in dieser Antwort aufgeführten Berechnungen sind nicht erforderlich.

1voto

Hitesh Punkte 605

Um es einfach auszudrücken. Ein Kalenderobjekt speichert Informationen über die Zeitzone, aber wenn Sie cal.getTime() ausführen, gehen die Zeitzoneninformationen verloren. Also für Zeitzone Konvertierungen werde ich raten, DateFormat Klassen zu verwenden...

1voto

Ingo Punkte 5017

Verwenden Sie diese Klasse, um immer die richtige UTC-Zeit von einem Online-NTP-Server zu erhalten:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

class NTP_UTC_Time
{
private static final String TAG = "SntpClient";

private static final int RECEIVE_TIME_OFFSET = 32;
private static final int TRANSMIT_TIME_OFFSET = 40;
private static final int NTP_PACKET_SIZE = 48;

private static final int NTP_PORT = 123;
private static final int NTP_MODE_CLIENT = 3;
private static final int NTP_VERSION = 3;

// Number of seconds between Jan 1, 1900 and Jan 1, 1970
// 70 years plus 17 leap days
private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;

private long mNtpTime;

public boolean requestTime(String host, int timeout) {
    try {
        DatagramSocket socket = new DatagramSocket();
        socket.setSoTimeout(timeout);
        InetAddress address = InetAddress.getByName(host);
        byte[] buffer = new byte[NTP_PACKET_SIZE];
        DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);

        buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);

        writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);

        socket.send(request);

        // read the response
        DatagramPacket response = new DatagramPacket(buffer, buffer.length);
        socket.receive(response);          
        socket.close();

        mNtpTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);            
    } catch (Exception e) {
      //  if (Config.LOGD) Log.d(TAG, "request time failed: " + e);
        return false;
    }

    return true;
}

public long getNtpTime() {
    return mNtpTime;
}

/**
 * Reads an unsigned 32 bit big endian number from the given offset in the buffer.
 */
private long read32(byte[] buffer, int offset) {
    byte b0 = buffer[offset];
    byte b1 = buffer[offset+1];
    byte b2 = buffer[offset+2];
    byte b3 = buffer[offset+3];

    // convert signed bytes to unsigned values
    int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0);
    int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1);
    int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2);
    int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3);

    return ((long)i0 << 24) + ((long)i1 << 16) + ((long)i2 << 8) + (long)i3;
}

/**
 * Reads the NTP time stamp at the given offset in the buffer and returns 
 * it as a system time (milliseconds since January 1, 1970).
 */    
private long readTimeStamp(byte[] buffer, int offset) {
    long seconds = read32(buffer, offset);
    long fraction = read32(buffer, offset + 4);
    return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L) / 0x100000000L);        
}

/**
 * Writes 0 as NTP starttime stamp in the buffer. --> Then NTP returns Time OFFSET since 1900
 */    
private void writeTimeStamp(byte[] buffer, int offset) {        
    int ofs =  offset++;

    for (int i=ofs;i<(ofs+8);i++)
      buffer[i] = (byte)(0);             
}

}

Und verwenden Sie es mit:

        long now = 0;

        NTP_UTC_Time client = new NTP_UTC_Time();

        if (client.requestTime("pool.ntp.org", 2000)) {              
          now = client.getNtpTime();
        }

Wenn Sie die UTC-Zeit "jetzt" als DateTimeString benötigen, verwenden Sie die Funktion:

private String get_UTC_Datetime_from_timestamp(long timeStamp){

    try{

        Calendar cal = Calendar.getInstance();
        TimeZone tz = cal.getTimeZone();

        int tzt = tz.getOffset(System.currentTimeMillis());

        timeStamp -= tzt;

        // DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault());
        DateFormat sdf = new SimpleDateFormat();
        Date netDate = (new Date(timeStamp));
        return sdf.format(netDate);
    }
    catch(Exception ex){
        return "";
     }
    } 

und verwenden Sie es mit:

String UTC_DateTime = get_UTC_Datetime_from_timestamp(now);

0 Stimmen

In single line <br/> <pre> <code>Calendar utcTime = Calendar.getInstance().add(Calendar.MILLISECOND, -time.getTimeZone().getOffset(time.getTimeInMillis()));</pre‌​> </code>

2 Stimmen

Ja, aber dies ruft die lokale Gerätezeit auf, die vom Benutzer manuell in eine falsche DateTime geändert werden kann

1voto

Gal Rom Punkte 5833

Dies ist meine Umsetzung:

public static String GetCurrentTimeStamp()
{
    Calendar cal=Calendar.getInstance();
    long offset = cal.getTimeZone().getOffset(System.currentTimeMillis());//if you want in UTC else remove it .
    return new java.sql.Timestamp(System.currentTimeMillis()+offset).toString();    
}

1voto

Wenn Sie das Parsen des Datums vermeiden möchten und nur einen Zeitstempel in GMT benötigen, können Sie verwenden:

final Date gmt = new Timestamp(System.currentTimeMillis()
            - Calendar.getInstance().getTimeZone()
                    .getOffset(System.currentTimeMillis()));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X