首页 文章

如何在Java中获取UTC或GMT中的当前日期和时间?

提问于
浏览
396

当我创建一个新的 Date 对象时,它被初始化为当前时间但在本地时区 . 如何获得GMT中的当前日期和时间?

30 回答

  • 3

    此代码打印当前时间UTC .

    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.TimeZone;
    
    
    public class Test
    {
        public static void main(final String[] args) throws ParseException
        {
            final SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
            f.setTimeZone(TimeZone.getTimeZone("UTC"));
            System.out.println(f.format(new Date()));
        }
    }
    

    结果

    2013-10-26 14:37:48 UTC
    
  • 2

    这是以String格式获取GMT时间的另一种方法

    String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z" ;
    final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
    sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
    String dateTimeString =  sdf.format(new Date());
    
  • 1

    如果您正在使用joda时间并希望在没有本地偏移的情况下以毫秒为单位的当前时间,您可以使用:

    long instant = DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), System.currentTimeMillis());
    
  • 359
    SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
    dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
    
    //Local time zone   
    SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
    
    //Time in GMT
    return dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
    
  • 5

    说实话 . 日历对象存储有关时区的信息,但是当您执行cal.getTime()时,时区信息将丢失 . 所以对于Timezone转换,我会建议使用DateFormat类...

  • 5

    这对我有用,返回格林尼治标准时间的时间戳!

    Date currDate;
        SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
        dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
        SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
    
        long currTime = 0;
        try {
    
            currDate = dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
            currTime = currDate.getTime();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
  • 0
    public class CurrentUtcDate 
    {
        public static void main(String[] args) {
            Date date = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
            dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
            System.out.println("UTC Time is: " + dateFormat.format(date));
        }
    }
    

    输出:

    UTC Time is: 22-01-2018 13:14:35
    

    您可以根据需要更改日期格式 .

  • 75

    java.util.Date 没有特定的时区,尽管其值通常被认为与UTC有关 . 是什么让你觉得它是在当地时间?

    确切地说: java.util.Date 中的值是自1970年1月1日午夜发布的Unix纪元以来的毫秒数 . 同一时期也可以在其他时区描述,但传统的描述是以UTC的形式 . 由于它是固定时期以来的毫秒数,因此无论当地时区如何, java.util.Date 内的值在任何特定时刻都是相同的 .

    我怀疑问题是你通过使用本地时区的Calendar实例显示它,或者可能使用也使用本地时区的 Date.toString()SimpleDateFormat 实例,默认情况下也使用本地时区 .

    如果这不是问题,请发布一些示例代码 .

    但是,无论如何,我建议您使用Joda-Time,它提供了更清晰的API .

  • 6

    这是我的实施:

    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();    
    }
    
  • 3

    这肯定会返回UTC时间:作为String和Date对象!

    static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss"
    
    public static Date GetUTCdatetimeAsDate()
    {
        //note: doesn't check for null
        return StringDateToDate(GetUTCdatetimeAsString());
    }
    
    public static String GetUTCdatetimeAsString()
    {
        final SimpleDateFormat sdf = new SimpleDateFormat(DATEFORMAT);
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        final String utcTime = sdf.format(new Date());
    
        return utcTime;
    }
    
    public static Date StringDateToDate(String StrDate)
    {
        Date dateToReturn = null;
        SimpleDateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);
    
        try
        {
            dateToReturn = (Date)dateFormat.parse(StrDate);
        }
        catch (ParseException e)
        {
            e.printStackTrace();
        }
    
        return dateToReturn;
    }
    
  • 48

    日历aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone(“GMT”));然后,使用aGMTCalendar对象执行的所有操作都将使用GMT时区完成,并且不会应用夏令时或应用固定偏移

    错误!

    Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    aGMTCalendar.getTime(); //or getTimeInMillis()
    

    Calendar aNotGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));aNotGMTCalendar.getTime();
    

    将返回同一时间 . 同意

    new Date(); //it's not GMT.
    
  • 0

    这适用于在Android中获取UTC毫秒 .

    Calendar c = Calendar.getInstance();
    int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);  
    Long utcMilliseconds = c.getTimeInMillis() + utcOffset;
    
  • 6

    这里有另一个获取GMT时间戳对象的建议:

    import java.sql.Timestamp;
    import java.util.Calendar;
    
    ...
    
    private static Timestamp getGMT() {
       Calendar cal = Calendar.getInstance();
       return new Timestamp(cal.getTimeInMillis()
                           -cal.get(Calendar.ZONE_OFFSET)
                           -cal.get(Calendar.DST_OFFSET));
    }
    
  • 14

    如果您想避免解析日期并且只想在GMT中使用时间戳,您可以使用:

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

    你可以直接使用它

    SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
    dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
    System.out.println(dateFormatGmt.format(new Date())+"");
    
  • 65
    Calendar c = Calendar.getInstance();
        System.out.println("current: "+c.getTime());
    
        TimeZone z = c.getTimeZone();
        int offset = z.getRawOffset();
        if(z.inDaylightTime(new Date())){
            offset = offset + z.getDSTSavings();
        }
        int offsetHrs = offset / 1000 / 60 / 60;
        int offsetMins = offset / 1000 / 60 % 60;
    
        System.out.println("offset: " + offsetHrs);
        System.out.println("offset: " + offsetMins);
    
        c.add(Calendar.HOUR_OF_DAY, (-offsetHrs));
        c.add(Calendar.MINUTE, (-offsetMins));
    
        System.out.println("GMT Time: "+c.getTime());
    
  • 5

    tl;博士

    Instant.now()   // Capture the current moment in UTC.
    

    生成一个String来表示该值:

    Instant.now().toString()
    

    2016-09-13T23:30:52.123Z

    详情

    the correct answer by Jon Skeet所述,java.util.Date对象具有 no time zone † . 但它的toString实现在生成该日期时间值的String表示时应用JVM的默认时区 . 对于天真的程序员来说,一个日期似乎有一个时区,但却没有 .

    与Java捆绑在一起的 java.util.Datej.u.Calendarjava.text.SimpleDateFormat 类是众所周知的麻烦 . Avoid them. 而是使用这些主管日期时间库中的任何一个:

    Java 8中的

    java.time(Java 8)

    Java 8带来了一个优秀的新java.time.* package来取代旧的java.util.Date/Calendar类 .

    获取UTC / GMT的当前时间是一个简单的单线程...

    Instant instant = Instant.now();
    

    Instant类是java.time中的基本构建块,表示UTC中时间轴上的时刻,分辨率为nanoseconds .

    在Java 8中,当前时刻仅以毫秒分辨率捕获 . 根据主机时钟硬件的能力,ClockClock捕获当前时刻,达到此类的全纳秒级能力 .

    它的 toString 方法使用one specific ISO 8601 format生成其值的String表示 . 该格式根据需要输出零,三,六或九位数字(millisecondsmicrosecondsnanoseconds)来表示秒数 .

    如果您想要更灵活的格式化或其他附加功能,则为UTC本身(ZoneOffset.UTC constant)应用UTC的偏移量为零,以获得OffsetDateTime .

    OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );
    

    转储到控制台......

    System.out.println( "now: " + now );
    

    跑的时候......

    now: 2014-01-21T23:42:03.522Z
    

    java.time类由JSR 310定义 . 他们的灵感来自Joda-Time,但完全是重新设计的 .

    Joda-Time

    更新:Joda-Time项目,现在在maintenance mode,建议迁移到java.time类 .

    使用Joda-Time第三方开源免费库,您只需一行代码即可获得当前日期时间 .

    Joda-Time启发了Java 8中新的java.time . *类,但它们具有不同的架构 . 您可以在旧版本的Java中使用Joda-Time . Joda-Time继续在Java 8中工作并继续积极维护(截至2014年) . 但是,Joda-Time团队确实建议迁移到java.time .

    System.out.println( "UTC/GMT date-time in ISO 8601 format: " + new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ) );
    

    更详细的示例代码(Joda-Time 2.3)......

    org.joda.time.DateTime now = new org.joda.time.DateTime(); // Default time zone.
    org.joda.time.DateTime zulu = now.toDateTime( org.joda.time.DateTimeZone.UTC );
    

    转储到控制台......

    System.out.println( "Local time in ISO 8601 format: " + now );
    System.out.println( "Same moment in UTC (Zulu): " + zulu );
    

    跑的时候......

    Local time in ISO 8601 format: 2014-01-21T15:34:29.933-08:00
    Same moment in UTC (Zulu): 2014-01-21T23:34:29.933Z
    

    有关执行时区工作的更多示例代码,请参阅my answer以查找类似问题 .

    时区

    我建议你总是指定一个时区,而不是隐含地依赖于JVM当前的默认时区(可以随时改变!) . 这种依赖似乎是造成日期工作混乱和错误的常见原因 .

    当调用 now() 时,传递要分配的期望/预期时区 . 使用DateTimeZone类 .

    DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
    DateTime now = DateTime.now( zoneMontréal );
    

    该 class 拥有constant for UTC时区 .

    DateTime now = DateTime.now( DateTimeZone.UTC );
    

    如果您确实想要使用JVM的当前默认时区,请进行显式调用,以便您的代码可以自我记录 .

    DateTimeZone zoneDefault = DateTimeZone.getDefault();
    

    ISO 8601

    阅读ISO 8601格式 . java.time和Joda-Time都使用该标准的敏感格式作为解析和生成字符串的默认格式 .


    †实际上,java.util.Date确实有一个时区,深埋在源代码层之下 . 出于大多数实际目的,该时区被忽略 . 所以,作为简写,我们说java.util.Date没有时区 . 此外,埋藏时区不是Date的 toString 方法所使用的时区;该方法使用JVM的当前默认时区 . 更有理由避免这种令人困惑的类并坚持使用Joda-Time和java.time .

  • 258

    如果你想要一个Date字段对象的字段调整为UTC,你可以这样做Joda Time

    import org.joda.time.DateTimeZone;
    import java.util.Date;
    
    ...
    
    Date local = new Date();
    System.out.println("Local: " + local);
    DateTimeZone zone = DateTimeZone.getDefault();
    long utc = zone.convertLocalToUTC(local.getTime(), false);
    System.out.println("UTC: " + new Date(utc));
    
  • 1

    为了使这更简单,在 UTC 中创建一个 Date ,你可以使用Calendar

    Calendar.getInstance(TimeZone.getTimeZone("UTC"));
    

    这将使用"UTC" TimeZoneCalendar 构造一个新实例 .

    如果您需要该日历中的 Date 对象,则可以使用 getTime() .

  • 2

    用于在特定时区和特定格式中呈现系统时间的示例代码 .

    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.TimeZone;
    
    public class TimZoneTest {
        public static void main (String[] args){
            //<GMT><+/-><hour>:<minutes>
            // Any screw up in this format, timezone defaults to GMT QUIETLY. So test your format a few times.
    
            System.out.println(my_time_in("GMT-5:00", "MM/dd/yyyy HH:mm:ss") );
            System.out.println(my_time_in("GMT+5:30", "'at' HH:mm a z 'on' MM/dd/yyyy"));
    
            System.out.println("---------------------------------------------");
            // Alternate format 
            System.out.println(my_time_in("America/Los_Angeles", "'at' HH:mm a z 'on' MM/dd/yyyy") );
            System.out.println(my_time_in("America/Buenos_Aires", "'at' HH:mm a z 'on' MM/dd/yyyy") );
    
    
        }
    
        public static String my_time_in(String target_time_zone, String format){
            TimeZone tz = TimeZone.getTimeZone(target_time_zone);
            Date date = Calendar.getInstance().getTime();
            SimpleDateFormat date_format_gmt = new SimpleDateFormat(format);
            date_format_gmt.setTimeZone(tz);
            return date_format_gmt.format(date);
        }
    
    }
    

    产量

    10/08/2011 21:07:21
    at 07:37 AM GMT+05:30 on 10/09/2011
    at 19:07 PM PDT on 10/08/2011
    at 23:07 PM ART on 10/08/2011
    
  • 0

    您可以使用:

    Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    

    然后,使用aGMTCalendar对象执行的所有操作都将使用GMT时区完成,并且不会应用夏令时或固定偏移 . 我认为前面的海报是正确的,Date()对象总是返回GMT,直到你对日期对象做一些转换为本地时区的事情 .

  • 6

    这是我对toUTC的实现:

    public static Date toUTC(Date date){
        long datems = date.getTime();
        long timezoneoffset = TimeZone.getDefault().getOffset(datems);
        datems -= timezoneoffset;
        return new Date(datems);
    }
    

    可能有几种方法可以改进它,但它对我有用 .

  • 1

    使用java.time包并包含以下代码 -

    ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );

    要么

    LocalDateTime now2 = LocalDateTime.now( ZoneOffset.UTC );

    取决于您的应用需求 .

  • 3
    SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
    dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
    System.out.println(dateFormatGmt.format(date));
    
  • 10

    附:

    Calendar cal = Calendar.getInstance();
    

    然后 cal 有当前的日期和时间 .
    您还可以通过以下方式获取时区的当前日期和时间:

    Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));
    

    您可以询问 cal.get(Calendar.DATE); 或其他日历常量关于其他详细信息 .
    Java中不推荐使用日期和时间戳 . 日历类不是 .

  • 1

    实际上不是时间,但它的表现可以改变 .

    SimpleDateFormat f = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
    f.setTimeZone(TimeZone.getTimeZone("UTC"));
    System.out.println(f.format(new Date()));
    

    地球的任何一点都有相同的时间,但我们对时间的看法可能因位置而异 .

  • 15

    Jon Skeet问道:

    @Downvoter:关注评论?我的回答到底是什么不对? - Jon Skeet 09年10月26日21:09

    我不是Downvoter,但这个答案似乎是不正确的 . 你说:

    java.util.Date始终为UTC . 是什么让你觉得它是在当地时间?我怀疑问题是你通过使用本地时区的Calendar实例显示它,或者可能使用也使用本地时区的Date.toString() .

    但是,代码:

    System.out.println(new java.util.Date().getHours() + " hours");
    

    给出当地时间,而不是GMT(UTC小时),根本不使用 Calendar ,也不使用 SimpleDateFormat .

    这就是为什么似乎有些不正确的原因 .

    汇总答案,代码:

    System.out.println(Calendar.getInstance(TimeZone.getTimeZone("GMT"))
                               .get(Calendar.HOUR_OF_DAY) + " Hours");
    

    显示GMT小时而不是当地小时 - 请注意 getTime.getHours() 缺失,因为这会创建一个 Date() 对象,理论上会将日期存储在GMT中,但会返回当地时区的小时数 .

  • 209

    使用此类从联机NTP服务器获得正确的UTC时间:

    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);             
    }
    
    }
    

    并使用它:

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

    如果你需要UTC时间“现在”作为DateTimeString使用函数:

    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 "";
         }
        }
    

    并使用它:

    String UTC_DateTime = get_UTC_Datetime_from_timestamp(now);
    
  • 7
    public static void main(String args[]){
        LocalDate date=LocalDate.now();  
        System.out.println("Current date = "+date);
    }
    
  • 12

    Converting Current DateTime in UTC:

    DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    
    DateTimeZone dateTimeZone = DateTimeZone.getDefault(); //Default Time Zone
    
    DateTime currDateTime = new DateTime(); //Current DateTime
    
    long utcTime = dateTimeZone.convertLocalToUTC(currDateTime .getMillis(), false);
    
    String currTime = formatter.print(utcTime); //UTC time converted to string from long in format of formatter
    
    currDateTime = formatter.parseDateTime(currTime); //Converted to DateTime in UTC
    

相关问题