当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何在Java中获取UTC或GMT中的当前日期和时间?》经验,为你挑选了17个好方法。

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



1> Jon Skeet..:

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

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

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

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

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


根据http://stackoverflow.com/questions/4123534/before-writing-a-java-date-to-an-sql-timestamp-column-does-jdbc-translate-the-da/4124620#4124620,Behrang, MySQL JDBC驱动程序将给定的`java.util.Timestamp`(或`java.util.Date`)转换为服务器时区.
@KanagaveluSugumar:`toString()`总是使用默认时区.`date.getTime()`肯定会返回自Unix时代以来的毫秒,以UTC为单位.最准确地说,"日期"本身根本没有时区 - 它只是*瞬间,可以在多个时区中看到.但是当你创建一个实例时,它*不依赖于你的时区.
@Jemenake:实际上在格林威治午夜时没有发生,因为英国当时的UTC + 1.只是历史上的一个奇怪的部分.但我明白你的观点 - 最好说"new Date().getTime()返回自Unix时代以来的毫秒,即1970年1月1日午夜的UTC".因此,UTC是将时代固定到特定时刻的一部分,而不是结果的一部分.
那可能是司机问题.您可能需要将连接设置为UTC或类似的东西.我以前见过这样的问题,但问题不在java.util.Date中.
@先生.猫:你是怎么决定的?是通过编写`System.out.println(new Date())`吗?如果是这样,你应该知道它是`toString()`方法,它在那里应用时区......如果不是这样,请提供更多细节.
"Date"文档声明:"虽然Date类旨在反映协调世界时(UTC),但它可能不会完全这样做,具体取决于Java虚拟机的主机环境." 例如在我的机器或我的Android手机中,当我初始化一个新的Date对象时,设置为GMT而不是UTC.没有我的贬低,也许我明白错了.
@OvidiuLatcu:这只是在谈论系统时钟的准确性可能受到限制的事实.我怀疑你指的是`Date.toString()`的结果,这只是一个显示问题.但无论如何,GMT和UTC实际上是相同的时区.(有一些非常微妙的差异,但在这里没有什么值得关注的.)
@tgkprog:我建议你提出一个新的问题,你的确切要求,你尝试过的等等.目前我们不知道你是否真的在寻找一个文本表示,整数值,以便你可以测试像"是八月吗?" 你绝对不应该忽视`Date`方法的弃用 - 国际化只是它们的错误的一部分,尽管它总是使用系统默认时区这一事实的一个症状.那里的文件很差:(
@tgkprog:我很高兴它帮助了你,即使你从未真正解释过你的问题......
我使用了一个新的Date()对象并插入到DB表中.DB是MySQL,当我在MySQL中使用UTC_TIMESTAMP()函数时,它可以正常工作,但是当我插入新Date()的值时,它会插入到我的本地时区.
@KanagaveluSugumar:嗯,文件?`getTime()`state的文档:"返回自此Date对象表示的1970年1月1日00:00:00 GMT以来的毫秒数."
@tgkprog:你假设OP想要一个字符串.没有迹象表明情况就是这样.
@tgkprog:您是否阅读过您在那里调用的已弃用方法的文档?(注意:"在本地时区解释".)关于需要更改"日期"内容以获取UTC的结论完全不正确.

2> 小智..:
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()) );


为什么在使用dateFormatGmt格式后使用dateFormatLocal解析...通过阅读它没有意义.我相信它有效,但只是想知道?
但时间取决于设备设定时间.如果用户在他的设备上设置了错误的时间,那么你将得到错误的UTC.如果我错了,请纠正我
协调世界时(UTC)与格林威治标准时间(GMT)之间没有时差
setTimeZone做到了(我猜你也可以使用与GMT相同的getTimeZone("UTC")?)

3> Basil Bourqu..:
TL;博士
Instant.now()   // Capture the current moment in UTC. 

生成一个String来表示该值:

Instant.now().toString()  

2016-09-13T23:30:52.123Z

细节

正如Jon Skeet所说的正确答案所述,java.util.Date对象没有时区.但是,toString在生成该日期时间值的String表示时,其实现应用JVM的默认时区.令这个天真的程序员感到困惑的是,Date 似乎有一个时区,但却没有.

java.util.Date,j.u.Calendar以及java.text.SimpleDateFormat与Java绑定类是出了名的麻烦.避免他们.相反,使用这些主管日期时间库中的任何一个:

Java 8中的java.time.*包

乔达时间

java.time(Java 8)

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

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

Instant instant = Instant.now();

Instant类是java.time基本构建块,代表时间线上的时刻UTC,分辨率为纳秒.

在Java 8中,当前时刻仅以毫秒分辨率捕获.Java 9带来了一种全新的实现,Clock可以捕获当前时刻,达到该类的全纳秒级能力,具体取决于主机时钟硬件的能力.

它的toString方法使用一种特定的ISO 8601格式生成其值的String表示.该格式根据需要输出零,三,六或九位数字(毫秒,微秒或纳秒)来表示秒数.

如果您想要更灵活的格式化或其他附加功能,那么对于UTC本身(ZoneOffset.UTC常量),应用UTC的偏移量为零,以获得a 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项目建议迁移到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

有关执行时区工作的更多示例代码,请参阅我对类似问题的回答.

时区

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

当呼叫java.util.Date通过要分配的期望/预期时区时.使用该Calendar课程.

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

该类保持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 SimpleDateFormat方法使用的时区; 该方法使用JVM的当前默认时区.更有理由避免这种令人困惑的类并坚持使用Joda-Time和java.time.



4> Someone Some..:

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

static final String DATE_FORMAT = "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(DATE_FORMAT);
    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;
}


请避免在Java中使用大写字母启动方法名称.有关方法名称,请参阅[Java编码约定](http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-135099.html#367).
重定向到此答案后,如果设备时间错误,则调用`new Date()`将永远不会返回正确的UTC时间。

5> Ahmad Nadeem..:
    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());



6> Antonio..:

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

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

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



7> simpatico..:

日历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.



8> Adam..:

此代码打印当前时间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



9> moberme..:

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

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


只需要减去偏移量?

10> 小智..:

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时间),使用no Calendar和no SimpleDateFormat.

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

汇总答案,代码:

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

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


我之前没有看过这个答案,但是如果你阅读了不推荐使用的`Date.getHours()`方法的文档,那就非常清楚了:"返回的值是一个数字(0到23),代表了包含或以此Date对象表示的时间开始的日期,**在本地时区**中解释." (强调我的.)这是`getHours()`方法,它解释了本地时区内的值 - 它不是'Date`对象本身状态的一部分.
正如Jon Skeet所说,java.util.Date对象**没有时区**.但令人困惑的是,方法`toString`和`getHours`将默认时区应用于它们的输出.所以,天真的程序员很容易被愚弄,因为它似乎*一个日期有一个时区,但实际上并没有.

11> 小智..:

如果你想要一个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));



12> mjh2007..:

您可以使用:

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

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



13> 小智..:
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(date));



14> nithinreddy..:

你可以直接使用它

SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(new Date())+"");



15> user2427..:

附:

Calendar cal = Calendar.getInstance();

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

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

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


不推荐使用Date和Timestamp的某些方法和构造函数,但类本身不是.

16> 小智..:

这里有另一个获取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));
}



17> 小智..:

这是以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());

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有