简体   繁体   English

Java SimpleDateFormat.parse()由于DST错误

[英]Java SimpleDateFormat.parse() Error due to DST

We ran into an issue with a job when it tried to use a SimpleDateFormat.parse(datestr) call when the datestr included times that happened to fall within DST rules (ie a ParseException happened with 20140309020100 ( yyyyMMddHHmmss ). datestr包含恰好在DST规则之内的时间时SimpleDateFormat.parse(datestr)20140309020100yyyyMMddHHmmss发生了ParseException SimpleDateFormat.parse(datestr)当它尝试使用SimpleDateFormat.parse(datestr)调用时,我们遇到了一个问题。

I am trying to build code to handle this issue and make it generic to work with all our different formats: 我正在尝试构建代码来处理此问题,并使其通用以与我们所有不同的格式一起使用:

public static Date validDateTimestamp(String datetime, String [] formats) 
throws ParseException
{
    for (int inx=0; inx < formats.length; inx++)  
    { 
        try {
          return checkDateFormat(datetime, formats[inx]);

        }
        catch (ParseException e1)
        {
           // ignore this error, just try the next format
        }
    }
// no good date returned using any format, throw an exception
throw new ParseException("bad date: " + datetime, 0);
}
private static Date checkDateFormat(String datetime, String format) 
throws ParseException
{
    SimpleDateFormat sdFormat = new SimpleDateFormat(format);
    sdFormat.setLenient(false);
    try {
        return sdFormat.parse(datetime);
     } catch (ParseException e)
     {
        throw e;
     }
}

This still has the same issue as before ( ParseException for datetime ). 这仍然具有与以前相同的问题( datetime ParseException )。

I have tried associating the SimpleDateFormat to a TimeZone , but that made it so that the returned date was offset by 5 hours. 我尝试将SimpleDateFormat关联到TimeZone ,但是这样做使得返回的日期偏移了5个小时。

TimeZone utc = TimeZone.getTimeZone("UTC");
sdFormat.setTimeZone(utc);

Is there a way to use a SimpleDateFormat to parse a date so that it doesn't change the datetime from what was passed in on the String, will ensure that the date is valid, and also will ignore Daylight Saving Time offsets (ie won't throw a ParseException )? 有没有一种方法可以使用SimpleDateFormat来解析日期,以使它不会更改String上传递的日期时间,将确保该日期有效,并且还将忽略夏时制偏移量(即,“抛出ParseException )?

We are not looking to add any new libraries to the project, but to get it working with the standard Java classes. 我们不打算在项目中添加任何新库,而是希望它与标准Java类一起使用。


Based on the answer from @GriffeyDog..... 根据@GriffeyDog的回答.....

The Date object returned from the SimpleDateFormat.parse() call will be in the timezone of where it is run. SimpleDateFormat.parse()调用返回的Date对象将在其运行的时区中。 In my case, EDT. 就我而言,EDT。 Even setting the timezone of the SimpleDateFormat will not help with that - other than the fact that it will parse what was a bad datetimestamp for EDT; 即使设置SimpleDateFormat的时区也无济于事-除了它会解析对于EDT不好的datetimestamp以外的事实。 what will get into the Date object will be converted to local time. Date对象中将获取的内容将转换为本地时间。 Since changing the JVM settings for this are not a viable option (shared servers), instead I modified the code as follows: 由于为此更改JVM设置不是一个可行的选择(共享服务器),因此我如下修改了代码:

  • Have both methods return a String value 让两个方法都返回一个String
  • Modify checkDateFormat so that instead of returning sdFormat.parse(datetime) it assigns that to a Date object 修改checkDateFormat以便将其分配给Date对象,而不是返回sdFormat.parse(datetime)
  • Set a new format to standardize a date return String - yyyyMMdd HH:mm:ss 设置新格式以标准化日期返回String yyyyMMdd HH:mm:ss
  • Use that format to return a String of the date - sdFormat.format(date) 使用该格式返回日期的String sdFormat.format(date)
  • Modify the Oracle calls that did something with the date to use Oracle's to_date() function instead of relying on conversion of a Date object 修改使用日期执行某些操作的Oracle调用以使用Oracle的to_date()函数,而不是依赖于Date对象的转换

This seems to do what we want. 这似乎可以满足我们的要求。 20140309020500 will now be allowed as a valid date. 现在将允许20140309020500作为有效日期。

You are returning a Date object, which represents an exact number of milliseconds since 1/1/1970 00:00 UTC. 您将返回一个Date对象,该对象表示自1970年1月1日00:00 UTC以来的确切毫秒数。 A SimpleDateFormat#parse cannot give you such a Date object if you're not providing it with a valid date/time. 如果您未向其提供有效的日期/时间,则SimpleDateFormat#parse无法为您提供这样的Date对象。 In order to convert your date/time string into a Date , SimpleDateFormat needs a time zone to work with. 为了将您的日期/时间字符串转换为DateSimpleDateFormat需要一个时区。 It will use your default locale's time zone if you don't provide it with one. 如果您未提供默认语言环境的时区,它将使用您的默认语言环境。 And in your default time zone, DST exists, and you are not providing a valid date/time string for those considerations. 并且在您的默认时区中,DST存在,并且您没有为这些注意事项提供有效的日期/时间字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM