在Java中以UTC格式获取日期对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22091107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 13:33:21  来源:igfitidea点击:

Get Date Object In UTC format in Java

javasimpledateformat

提问by Ninad Pingale

I have written following code. I want to get Date object in UTC format.

我写了以下代码。我想以 UTC 格式获取 Date 对象。

I am able to get expected date string in UTC using SimpleDateFormat. But using same SimpleDateFormatobject, I am not able to get object in UTC format. It is returning object with IST format.

我能够使用 UTC 获得预期的日期字符串SimpleDateFormat。但是使用相同的SimpleDateFormat对象,我无法以 UTC 格式获取对象。它以 IST 格式返回对象。

After searching, I found that Date object doesn't store timestamp info.

搜索后,我发现 Date 对象不存储时间戳信息。

How can I get date object in UTC format ?

如何获取 UTC 格式的日期对象?

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class dddd {

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("Input - "+1393572325000L);
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date date= new Date(1393572325000L);  
        String dateString = formatter.format(date);

        System.out.println("Converted UTC TIME (using Format method) : "+dateString);

        Date date2 =null;
        try {
            date2 = formatter.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }


        System.out.println("Parsed Date Object (using Parse method) : "+date2);

        System.out.println("Expected Date Object : Fri Feb 28 07:25:25 UTC 2014");

    }

}

This prints following output :

这将打印以下输出:

Input - 1393572325000
Converted UTC TIME (using Format method) : 2014-02-28 07:25:25
Parsed Date Object (using Parse method) : Fri Feb 28 12:55:25 IST 2014
Expected Date Object : Fri Feb 28 07:25:25 UTC 2014

回答by JB Nizet

A Date doesn't have any time zone. What you're seeing is only the formatting of the date by the Date.toString()method, which uses your local timezone, always, to transform the timezone-agnostic date into a String that you can understand.

日期没有任何时区。您所看到的只是该Date.toString()方法的日期格式,该方法始终使用您的本地时区,将与时区无关的日期转换为您可以理解的字符串。

If you want to display the timezone-agnostic date as a string using the UTC timezone, then use a SimpleDateFormat with the UTC timezone (as you're already doing in your question).

如果您想使用 UTC 时区将与时区无关的日期显示为字符串,请使用 SimpleDateFormat 和 UTC 时区(正如您已经在问题中所做的那样)。

In other terms, the timezone is not a property of the date. It's a property of the format used to transform the date into a string.

换句话说,时区不是日期的属性。它是用于将日期转换为字符串的格式的属性。

回答by Dipali Vasani

final Date currentTime = new Date();
final SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("UTC time: " + sdf.format(currentTime));

回答by Basil Bourque

tl;dr

tl;博士

Instant.ofEpochMilli ( 1_393_572_325_000L )
       .toString()

2014-02-28T07:25:25Z

2014-02-28T07:25:25Z

Details

细节

(a) You seem be confused as to what a Date is. As the answer by JB Nizetsaid, a Date tracks the number of milliseconds since the Unixepoch(first moment of 1970) in the UTCtime zone (that is, with no time zone offset). So a Date has no time zone?. And it has no "format". We create string representations froma Date's value, but the Date itself is not a String and has no String.

(a) 您似乎对日期是什么感到困惑。正如JB Nizet回答所说,Date 跟踪自UTC时区(即没有时区偏移)的Unix纪元(1970 年的第一时刻)以来的毫秒数。所以 Date 没有时区. 它没有“格式”。我们Date 的值创建字符串表示,但Date 本身不是 String 并且没有 String

(b) You refer to a "UTC format". UTC is not a format, not I have heard of. UTC (Coordinated Universal Time)is the origin point of time zones. Time zones east of the Royal Observatory in Greenwich, London are some number of hours & minutes ahead of UTC. Westward time zones are behind UTC.

(b) 您指的是“UTC 格式”。UTC 不是一种格式,我没有听说过。UTC(协调世界时)是时区的起点。伦敦格林威治皇家天文台以东的时区比 UTC 早一些小时和分钟。西部时区落后于UTC。

You seem to be referring to ISO 8601formatted strings. You are using the optional format, omitting (1) the Tfrom the middle, and (2) the offset-from-UTC at the end. Unless presenting the string to a user in the user interface of your app, I suggest you generally stick with the usual format:

您似乎指的是ISO 8601格式的字符串。您正在使用可选格式,省略 (1)T中间的和 (2) 末尾的偏移量。除非在您的应用程序的用户界面中将字符串呈现给用户,否则我建议您通常坚持使用通常的格式:

  • 2014-02-27T23:03:14+05:30
  • 2014-02-27T23:03:14Z('Z' for Zulu, or UTC, with an offset of +00:00)
  • 2014-02-27T23:03:14+05:30
  • 2014-02-27T23:03:14Z(“Z”代表祖鲁语或 UTC,偏移量为 +00:00)

(c) Avoid the 3 or 4 letter time zone codes. They are neither standardized nor unique. "IST" for example can mean either Indian Standard Timeor Irish Standard Time.

(c) 避免使用 3 或 4 个字母的时区代码。它们既不标准化也不独特。例如,“IST”可以表示印度标准时间爱尔兰标准时间

(d) Put some effort into searching StackOverflow before posting. You would have found all your answers.

(d) 在发帖前努力搜索 StackOverflow。你会找到你所有的答案。

(e) Avoid the java.util.Date & Calendar classes bundled with Java. They are notoriously troublesome. Use either the Joda-Timelibrary or Java 8's new java.time package (inspired by Joda-Time, defined by JSR 310).

(e) 避免使用 Java 捆绑的 java.util.Date 和 Calendar 类。他们是出了名的麻烦。使用Joda-Time库或 Java 8 的新 java.time 包(受 Joda-Time 启发,由 JSR 310 定义)。

java.time

时间

The java.time classes use standard ISO 8601 formats by default when parsing and generating strings.

java.time 类在解析和生成字符串时默认使用标准 ISO 8601 格式。

OffsetDateTime odt = OffsetDateTime.parse( "2014-02-27T23:03:14+05:30" ); 
Instant instant = Instant.parse( "2014-02-27T23:03:14Z" );

Parse your count of milliseconds since the epoch of first moment of 1970 in UTC.

解析自 UTC 时间 1970 年第一个时刻以来的毫秒数。

Instant instant = Instant.ofEpochMilli ( 1_393_572_325_000L );

instant.toString(): 2014-02-28T07:25:25Z

Instant.toString(): 2014-02-28T07:25:25Z

Adjust that Instantinto a desired time zone.

将其调整Instant为所需的时区。

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

zdt.toString(): 2014-02-28T02:25:25-05:00[America/Montreal]

zdt.toString(): 2014-02-28T02:25:25-05:00[美国/蒙特利尔]



About java.time

关于java.time

The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*classes.

您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

Where to obtain the java.time classes?

从哪里获得 java.time 类?

The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多



Joda-Time

乔达时间

UPDATE:The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

更新:现在处于维护模式Joda-Time项目建议迁移到java.time类。

Joda-Timeuses ISO 8601 as its defaults.

Joda-Time使用 ISO 8601 作为其默认值。

A Joda-Time DateTimeobject knows its on assigned time zone, unlike a java.util.Date object.

DateTime与 java.util.Date 对象不同,Joda-Time对象知道其指定的时区。

Generally better to specify a time zone explicitly rather than rely on default time zone.

通常最好明确指定时区而不是依赖默认时区。

Example Code

示例代码

long input = 1393572325000L;
DateTime dateTimeUtc = new DateTime( input, DateTimeZone.UTC );

DateTimeZone timeZoneIndia = DateTimeZone.forID( "Asia/Kolkata" );
DateTimeZone timeZoneIreland = DateTimeZone.forID( "Europe/Dublin" );

DateTime dateTimeIndia = dateTimeUtc.withZone( timeZoneIndia );
DateTime dateTimeIreland = dateTimeIndia.withZone( timeZoneIreland );

// Use a formatter to create a String representation. The formatter can adjust time zone if you so desire.
DateTimeFormatter formatter = DateTimeFormat.forStyle( "FM" ).withLocale( Locale.CANADA_FRENCH ).withZone( DateTimeZone.forID( "America/Montreal" ) );
String output = formatter.print( dateTimeIreland );

Dump to console…

转储到控制台...

// All three of these date-time objects represent the *same* moment in the timeline of the Universe.
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "dateTimeIreland: " + dateTimeIreland );

System.out.println( "output for Montréal: " + output );

When run…

运行时…

dateTimeUtc: 2014-02-28T07:25:25.000Z
dateTimeIndia: 2014-02-28T12:55:25.000+05:30
dateTimeIreland: 2014-02-28T07:25:25.000Z
output for Montréal: vendredi 28 février 2014 02:25:25


?Actually, java.util.Date doeshave a time zone. That time zone is assigned deep in its source code. Yet the class ignores that time zone for most practical purposes. And its toStringmethod applies the JVM's current default time zone rather than that internal time zone. Confusing? Yes. This is one of many reasons to avoid the old java.util.Date/.Calendar classes. Use java.time and/or Joda-Time instead.

? 实际上, java.util.Date确实有一个时区。该时区在其源代码中被分配得很深。然而,出于大多数实际目的,该类忽略了该时区。并且它的toString方法应用 JVM 的当前默认时区而不是内部时区。令人困惑?是的。这是避免使用旧的 java.util.Date/.Calendar 类的众多原因之一。改用 java.time 和/或 Joda-Time。

回答by F?rat Kü?üK

You can subtract the time zone difference from now.

您可以从现在减去时区差异。

final Calendar calendar  = Calendar.getInstance();
final int      utcOffset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
final long     tempDate  = new Date().getTime();

return new Date(tempDate - utcOffset);

回答by Trilok Singh Devda

In java 8 , It's really easy to get timestamp in UTC by using java 8 java.time.Instantlibrary :

在 java 8 中,使用java 8 java.time.Instant库获取 UTC 时间戳真的很容易:

Instant.now();

That few word of code will return the UTC Timestamp.

这几个字的代码将返回 UTC 时间戳。