Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何设置java.util.Date的时区?_Java_Date_Timezone_Java.util.date - Fatal编程技术网

如何设置java.util.Date的时区?

如何设置java.util.Date的时区?,java,date,timezone,java.util.date,Java,Date,Timezone,Java.util.date,我已经从字符串中解析了java.util.Date,但它正在将本地时区设置为Date对象的时区 在解析日期的字符串中未指定时区。我想设置date对象的特定时区 我如何做到这一点?是仅使用JDK类处理时区的常用方法。有一些可能有用的其他选择/实用程序EditSpong的便条提醒我,我听说了很多很好的东西(尽管我自己没有使用过它)。使用DateFormat。比如说, SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:

我已经从
字符串中解析了
java.util.Date
,但它正在将本地时区设置为
Date
对象的时区

在解析日期的
字符串
中未指定时区。我想设置
date
对象的特定时区


我如何做到这一点?

是仅使用JDK类处理时区的常用方法。有一些可能有用的其他选择/实用程序EditSpong的便条提醒我,我听说了很多很好的东西(尽管我自己没有使用过它)。

使用DateFormat。比如说,

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

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


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

您还可以在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
tl;博士 …已解析…来自字符串…未指定时区…我要设置特定时区

j.u.Date中没有时区 正如其他正确答案所述,java.util.Date没有时区†。它表示/GMT(无时区偏移)。非常混乱,因为它的
toString
方法在生成字符串表示时应用JVM的默认时区

避免j.u.Date 出于这一点和许多其他原因,您应该避免使用内置的java.util.Date&.Calendar&java.text.simpleDataFormat。他们是出了名的麻烦

而是使用捆绑的

java.time time类可以用三种方式表示时间线上的一个时刻:

  • UTC(
    Instant
  • 带偏移量(
    OffsetDateTime
    ZoneOffset
  • 带时区(
    ZoneDateTime
    ZoneId
Instant
在中,基本构造块是UTC时间线上的一个时刻。对大部分业务逻辑使用
Instant
对象

Instant instant = Instant.now();
OffsetDateTime
应用一个调整到某个地方的

申请一份工作以获得一份工作

ZoneDateTime
更好的方法是应用偏移量加上处理异常的规则,例如

将a应用于
即时
以获取a。始终指定一个。切勿使用3-4个既不独特也不标准的缩写,如
EST
IST

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
LocalDateTime
如果输入字符串缺少偏移量或区域的任何指示符,则将其解析为一个

如果您确定预期时区,请指定一个
ZoneId
以生成
zoneDateTime
。参见上面tl中的代码示例;顶部是dr部分

格式化字符串 对这三个类中的任何一个调用
toString
方法,以生成表示标准格式的日期时间值的字符串。
zoneDateTime
类通过在括号中添加时区名称来扩展标准格式

String outputInstant = instant.toString(); // Ex: 2011-12-03T10:15:30Z
String outputOdt = odt.toString(); // Ex: 2007-12-03T10:15:30+01:00
String outputZdt = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]
对于其他格式,请使用类。通常,最好让该类使用用户期望的人类语言和文化规范生成本地化格式。也可以指定特定的格式



关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

该项目现已启动,建议迁移到类

您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
类。Hibernate5和JPA2.2支持java.time

从哪里获得java.time类

  • 、和更高版本-标准Java API的一部分,带有捆绑实现。
    • 带来了一些小功能和修复
    • 大多数java.time功能都在中向后移植到Java6和Java7
    • Android(26+)的更高版本捆绑了java.time类的实现

    • 对于早期的Android(如果您必须仅使用标准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;
      }
      

      这要归功于此。

      如果有人需要此功能,如果您需要将
      xmlgoriancalendar
      时区从UTC转换为当前时区,则只需将时区设置为
      0
      ,然后调用
      togregoriaancalendar()
      -它将保持相同的时区,但
      日期
      知道如何将其转换为您的时区,因此您可以从那里获取数据

      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
      

      将日期转换为字符串,并使用SimpleDataFormat进行转换

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

      此代码在我正在开发的应用程序中非常有用:

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

      在这里,您可以获得类似“2020-03-11T20:16:17”的日期,并返回“2020年3月11日-20:16”


      虽然不是你问题的真正答案,但在看到这里提到过几次之后,我已经使用了Joda Time。在我看来,它比标准API更合理,而且可以很容易地完成这类事情。@msandiford现在,使用java.Time类而不是Joda Time。项目现在开始了,团队建议迁移到类。See.在谷歌搜索、实验和解释之后,我意识到这是对答案的一个精确而有用的补充,值得强调的是:日期只包含毫秒值。如果你查看源代码,几乎只有一个
      long
      字段,名为
      fastTime
      Date.toString()
      实际上使用了一个
      日历
      来解释这个毫秒时间。所以打印出一个
      日期
      会让它看起来有一个
      /**
       * 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;
      }
      
      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
      
          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);
      
          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);
      
       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);
      }