266

我已经java.util.Date从 a 解析了 aString但它将本地时区设置为date对象的时区。

解析的Stringfrom which中未指定时区。Date我想设置date对象的特定时区。

我怎样才能做到这一点?

4

11 回答 11

356

使用日期格式。例如,

SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = isoFormat.parse("2010-05-23T09:01:02");
于 2010-05-23T10:49:56.900 回答
210

请注意,java.util.Date对象本身不包含任何时区信息 - 您无法在Date对象上设置时区。对象包含的唯一Date内容是自“纪元”(1970 年 1 月 1 日 00:00:00 UTC)以来的毫秒数。

正如 ZZ Coder 所示,您在DateFormat对象上设置时区,以告诉它您要在哪个时区显示日期和时间。

于 2010-05-23T14:45:21.760 回答
135
于 2014-03-02T10:45:36.023 回答
80

您还可以在 JVM 级别设置时区

Date date1 = new Date();
System.out.println(date1);

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
// or pass in a command line arg: -Duser.timezone="UTC"

Date date2 = new Date();
System.out.println(date2);

输出:

Thu Sep 05 10:11:12 EDT 2013
Thu Sep 05 14:11:12 UTC 2013
于 2013-09-05T14:15:18.240 回答
12

如果你必须只使用标准的 JDK 类,你可以使用这个:

/**
 * Converts the given <code>date</code> from the <code>fromTimeZone</code> to the
 * <code>toTimeZone</code>.  Since java.util.Date has does not really store time zome
 * information, this actually converts the date to the date that it would be in the
 * other time zone.
 * @param date
 * @param fromTimeZone
 * @param toTimeZone
 * @return
 */
public static Date convertTimeZone(Date date, TimeZone fromTimeZone, TimeZone toTimeZone)
{
    long fromTimeZoneOffset = getTimeZoneUTCAndDSTOffset(date, fromTimeZone);
    long toTimeZoneOffset = getTimeZoneUTCAndDSTOffset(date, toTimeZone);

    return new Date(date.getTime() + (toTimeZoneOffset - fromTimeZoneOffset));
}

/**
 * Calculates the offset of the <code>timeZone</code> from UTC, factoring in any
 * additional offset due to the time zone being in daylight savings time as of
 * the given <code>date</code>.
 * @param date
 * @param timeZone
 * @return
 */
private static long getTimeZoneUTCAndDSTOffset(Date date, TimeZone timeZone)
{
    long timeZoneDSTOffset = 0;
    if(timeZone.inDaylightTime(date))
    {
        timeZoneDSTOffset = timeZone.getDSTSavings();
    }

    return timeZone.getRawOffset() + timeZoneDSTOffset;
}

归功于这篇文章

于 2015-05-22T18:37:00.123 回答
6

java.util.Calendar是仅使用 JDK 类来处理时区的常用方法。Apache Commons有一些可能有用的替代方案/实用程序。编辑Spong 的笔记提醒我,我听说过关于Joda-Time 的好消息(尽管我自己没有使用过)。

于 2010-05-23T10:36:56.507 回答
2

在这里,您可以获得“2020-03-11T20:16:17”之类的日期并返回“11/Mar/2020 - 20:16”

 private String transformLocalDateTimeBrazillianUTC(String dateJson) throws  ParseException {
    String localDateTimeFormat = "yyyy-MM-dd'T'HH:mm:ss";
    SimpleDateFormat formatInput = new SimpleDateFormat(localDateTimeFormat);

    //Here is will set the time zone
    formatInput.setTimeZone(TimeZone.getTimeZone("UTC-03"));

    String brazilianFormat = "dd/MMM/yyyy - HH:mm";
    SimpleDateFormat formatOutput = new SimpleDateFormat(brazilianFormat);
    Date date = formatInput.parse(dateJson);
    return formatOutput.format(date);
}
于 2020-08-20T19:41:07.787 回答
1

将日期转换为字符串并使用 SimpleDateFormat 进行。

    SimpleDateFormat readFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    readFormat.setTimeZone(TimeZone.getTimeZone("GMT" + timezoneOffset));
    String dateStr = readFormat.format(date);
    SimpleDateFormat writeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    Date date = writeFormat.parse(dateStr);
于 2018-01-17T13:11:36.787 回答
1

此代码在我正在开发的应用程序中很有帮助:

    Instant date = null;
    Date sdf = null;
    String formatTemplate = "EEE MMM dd yyyy HH:mm:ss";
    try {
        SimpleDateFormat isoFormat = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss");
        isoFormat.setTimeZone(TimeZone.getTimeZone(ZoneId.of("US/Pacific")));
        sdf = isoFormat.parse(timeAtWhichToMakeAvailable);
        date = sdf.toInstant();

    } catch (Exception e) {
        System.out.println("did not parse: " + timeAtWhichToMakeAvailable);
    }

    LOGGER.info("timeAtWhichToMakeAvailable: " + timeAtWhichToMakeAvailable);
    LOGGER.info("sdf: " + sdf);
    LOGGER.info("parsed to: " + date);
于 2019-01-17T19:36:43.940 回答
0

如果有人需要这个,如果您需要将XMLGregorianCalendar时区从 UTC 转换为当前时区,那么您需要做的就是将时区设置为0,然后调用toGregorianCalendar()- 它将保持相同的时区,但Date知道如何将其转换为你的,所以你可以从那里获取数据。

XMLGregorianCalendar xmlStartTime = DatatypeFactory.newInstance()
    .newXMLGregorianCalendar(
        ((GregorianCalendar)GregorianCalendar.getInstance());
xmlStartTime.setTimezone(0);
GregorianCalendar startCalendar = xmlStartTime.toGregorianCalendar();
Date startDate = startCalendar.getTime();
XMLGregorianCalendar xmlStartTime = DatatypeFactory.newInstance()
    .newXMLGregorianCalendar(startCalendar);
xmlStartTime.setHour(startDate.getHours());
xmlStartTime.setDay(startDate.getDate());
xmlStartTime.setMinute(startDate.getMinutes());
xmlStartTime.setMonth(startDate.getMonth()+1);
xmlStartTime.setTimezone(-startDate.getTimezoneOffset());
xmlStartTime.setSecond(startDate.getSeconds());
xmlStartTime.setYear(startDate.getYear() + 1900);
System.out.println(xmlStartTime.toString());

结果:

2015-08-26T12:02:27.183Z
2015-08-26T14:02:27.183+02:00
于 2015-08-26T09:44:55.910 回答
0

这个答案可能是最短的,它只使用 Date 类:

long current = new Date().getTime() + 3_600_000;              //e.g. your JVM time zone +1 hour (3600000 milliseconds)
System.out.printf("%1$td.%1$tm.%1$tY %1$tH:%1$tM\n", current);//european time format

但是,如果可以的话,使用更现代的方法来做同样的事情。

于 2021-07-14T12:04:08.300 回答