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

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

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

30个解决方案

354 votes

Date.toString()没有特定的时区,尽管它的值通常与UTC相关。 是什么让你觉得它是在当地时间?

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

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

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

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

Jon Skeet answered 2019-01-06T23:07:15Z

258 votes

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

Dan answered 2019-01-06T23:07:31Z

206 votes

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实现在生成该日期时间值的字符串表示时应用JVM的默认时区。 对于天真的程序员来说,一个日期似乎有一个时区,但却没有。

与Java捆绑在一起的toString,j.u.Calendar和java.text.SimpleDateFormat类是众所周知的麻烦。 避免他们。 相反,使用这些主管日期时间库中的任何一个:

Java 8中的java.time。*包

乔达时间

java.time(Java 8)

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

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

Instant instant = Instant.now();

toString类是java.time中的基本构建块,表示UTC时间轴上的分钟,分辨率为纳秒。

在Java 8中,当前时刻仅以毫秒分辨率捕获。 Java 9带来了toString的全新实现,根据主机时钟硬件的能力捕获当前时刻,达到该级别的全纳秒级能力。

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

如果您想要更灵活的格式或其他附加功能,则为UTC本身(toString常量)应用从零开始的偏移量来获得toString。

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当前的默认时区(可以随时改变!)。 这种依赖似乎是造成日期工作混乱和错误的常见原因。

当呼叫toString时,传递要分配的期望/预期时区。 使用toString课程。

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

Basil Bourque answered 2019-01-06T23:10:47Z

75 votes

这肯定会返回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;

}

Someone Somewhere answered 2019-01-06T23:11:09Z

65 votes

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

Ahmad Nadeem answered 2019-01-06T23:11:25Z

48 votes

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

SimpleDateFormat f = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

f.setTimeZone(TimeZone.getTimeZone("UTC"));

System.out.println(f.format(new Date()));

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

Antonio answered 2019-01-06T23:11:53Z

15 votes

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

simpatico answered 2019-01-06T23:12:30Z

14 votes

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

Adam answered 2019-01-06T23:12:54Z

12 votes

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

Calendar c = Calendar.getInstance();

int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);

Long utcMilliseconds = c.getTimeInMillis() + utcOffset;

moberme answered 2019-01-06T23:13:16Z

10 votes

Jon Skeet问道:

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

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

getTime.getHours()始终为UTC格式。 是什么让你觉得它在当地   时间? 我怀疑问题是你是通过一个显示它   使用本地时区或可能使用的Calendar的实例   Date()也使用当地时区。

但是,代码:

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

给出当地时间,而不是格林尼治标准时间(UTC时间),根本不使用getTime.getHours()和Date()。

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

汇总答案,代码:

System.out.println(Calendar.getInstance(TimeZone.getTimeZone("GMT"))

.get(Calendar.HOUR_OF_DAY) + " Hours");

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

Dana Wilson answered 2019-01-06T23:14:32Z

7 votes

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

huljas answered 2019-01-06T23:14:54Z

6 votes

您可以使用:

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

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

mjh2007 answered 2019-01-06T23:15:18Z

6 votes

SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");

dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));

System.out.println(dateFormatGmt.format(date));

Justin answered 2019-01-06T23:15:34Z

6 votes

你可以直接使用它

SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");

dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));

System.out.println(dateFormatGmt.format(new Date())+"");

nithinreddy answered 2019-01-06T23:15:55Z

5 votes

附:

Calendar cal = Calendar.getInstance();

然后cal.get(Calendar.DATE);拥有当前的日期和时间。

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

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

您可以询问cal.get(Calendar.DATE);或其他日历常量关于其他详细信息。

Java中不推荐使用日期和时间戳。 日历类不是。

user2427 answered 2019-01-06T23:16:38Z

5 votes

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

}

Rene answered 2019-01-06T23:17:00Z

5 votes

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

shahtapa answered 2019-01-06T23:17:22Z

3 votes

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

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){

//:

// 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

so_mv answered 2019-01-06T23:17:46Z

3 votes

只是为了使这个更简单,在getTime()中创建Date即可使用Date:

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

这将使用“UTC”getTime()为Date构建新实例。

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

Ovidiu Latcu answered 2019-01-06T23:18:20Z

3 votes

以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

My God answered 2019-01-06T23:18:42Z

2 votes

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

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

}

Bogdan answered 2019-01-06T23:19:04Z

2 votes

public static void main(String args[]){

LocalDate date=LocalDate.now();

System.out.println("Current date = "+date);

}

Arjun Singh answered 2019-01-06T23:19:19Z

1 votes

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

Hitesh answered 2019-01-06T23:19:41Z

1 votes

这是我的实施:

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

}

Gal Rom answered 2019-01-06T23:20:03Z

1 votes

使用此类从联机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

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

Ingo answered 2019-01-06T23:20:44Z

1 votes

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

final Date gmt = new Timestamp(System.currentTimeMillis()

- Calendar.getInstance().getTimeZone()

.getOffset(System.currentTimeMillis()));

Matthias van der Vlies answered 2019-01-06T23:21:06Z

1 votes

这是我对toUTC的实现:

public static Date toUTC(Date date){

long datems = date.getTime();

long timezoneoffset = TimeZone.getDefault().getOffset(datems);

datems -= timezoneoffset;

return new Date(datems);

}

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

Ashallar answered 2019-01-06T23:21:34Z

0 votes

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

long instant = DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), System.currentTimeMillis());

Managarm answered 2019-01-06T23:21:56Z

0 votes

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

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

santoshlokhande answered 2019-01-06T23:22:19Z

0 votes

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

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

要么

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

取决于您的应用需求。

Asif answered 2019-01-06T23:22:57Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值