根据SimpleDateFormat类文档,Java它的日期模式不支持超过毫秒的时间粒度.
所以,日期字符串就像
通过模式解析时
实际上将.符号后面的整数解释为(接近10亿!)毫秒,而不是纳秒,导致日期
即超过11天.令人惊讶的是,使用较少数量的S符号仍会导致所有9位数被解析(而不是,例如,最左边的3位.SSS).
有两种方法可以正确处理此问题:
是否有任何其他方法可以通过向标准SimpleDateFormat实现提供模式来获得正确的解决方案,而无需任何其他代码修改或字符串操作?
我目前有一个Joda日期解析器,它使用DateTimeFormatterBuilder,我可能会收到六种不同的日期格式.
我正在迁移到Java 8的Date例程,并没有看到等效的.
如何使用Java 8 Dates做这样的事情?
DateTimeParser[] parsers = { 
    DateTimeFormat.forPattern( "yyyy/MM/dd HH:mm:ss.SSSSSS" ).getParser() ,
    DateTimeFormat.forPattern( "yyyy-MM-dd HH:mm:ss" ).getParser() ,
    DateTimeFormat.forPattern( "ddMMMyyyy:HH:mm:ss.SSS Z" ).getParser() ,
    DateTimeFormat.forPattern( "ddMMMyyyy:HH:mm:ss.SSS" ).getParser() ,
    DateTimeFormat.forPattern( "ddMMMyyyy:HH:mm:ss.SSSSSS" ).getParser() ,
    DateTimeFormat.forPattern( "yyyy-MM-dd HH:mm:ss.SSS" ).getParser() 
};
DateTimeFormatter dateTimeFormatterInput = new DateTimeFormatterBuilder()
     .append( null, parsers ).toFormatter();
我曾经使用像这样的Spring 属性来支持Java Date或Joda Localdate模式绑定DateTimeFormat pattern
@DateTimeFormat(pattern = "dd.MM.yyyy")
private LocalDate creationDate;
但我需要支持两种日期模式,例如:
如果用户输入31/12/1999或31/12/99,则两者都可以绑定到相同的值31/12/1999.是否可以为此定义两种模式@DateTimeFormat?
编辑:
我试图将模式更改为
@DateTimeFormat(pattern = "dd.MM.yy")
private LocalDate creationDate;
我发现它可以处理这两种情况(例如当用户输入31/12/1999或者31/12/99两者都受到约束时)31/12/1999.任何意见?
这是我将String解析成的方法LocalDateTime.
    public static String formatDate(final String date) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS");
        LocalDateTime formatDateTime = LocalDateTime.parse(date, formatter);
        return formatDateTime.atZone(ZoneId.of("UTC")).toOffsetDateTime().toString();
    }
但这仅适用于输入字符串, 
 2017-11-21 18:11:14.05
但无法2017-11-21 18:11:14.057
使用DateTimeParseException.
如何定义适用于.SS和.SSS?的格式化程序?
java datetime-format datetime-parsing java-time dateformatter
我正在尝试使用分析日期SimpleDateFormat.由于我的服务采用多种日期格式,我采用了这种方法:
String[] formats = {
        "yyyy-MM-dd'T'HH:mm:ss.SSSZ",
        "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
        "yyyy-MM-dd'T'HH:mm:ss.SSS-HH:mm",
        "EEE MMM dd HH:mm:ss Z yyyy"};
for (String format : formats)
{
    try
    {
        return new SimpleDateFormat(format).parse(dateString);
    }
    catch (ParseException e) {}
}
return null;
其背后的基本原理try-catch是,如果当前日期格式无法解析dateString,Exception则会抛出一个并且代码将继续循环,直到找到合适的日期格式或返回null.
该catch块简直就是有那么该try块将具有以下一些东西(如果没有遵循可能发生编译错误try).
我可以保持代码原样,但空catch块是不好的做法.将来维持其他人也会感到困惑.它简直不优雅.
我可以在catch块中添加以下内容:
catch (Exception e)
{
    if (!(e instanceof ParseException))
    {
        throw e;
    }
}
但同样,内部的代码没有任何意义,因为没有Exception其他的ParseException可以被try块抛出(我NullPointerException …
我想要一个通用的快速解析器来处理随机格式的日期:
有一种不错的方法吗?
目前,我正计划使用以下方式:
val formatter = new DateTimeFormatterBuilder()
  .appendPattern("[yyyy-MM-dd'T'HH:mm:ss]")
  .appendPattern("[yyyy-MM-dd]")
  .appendPattern("[yyyy]")
  // add so many things here
  .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
  .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
  .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
  .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
  .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
  .parseDefaulting(ChronoField.MICRO_OF_SECOND, 0)
  .toFormatter()
val temporalAccessor = formatter.parse("2018")
val localDateTime = LocalDateTime.from(temporalAccessor)
localDateTime.getHour
val zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.systemDefault)
val result = Instant.from(zonedDateTime)
但是,有比指定数百种格式更聪明的方法吗?
我发现的大多数答案都是过时的(在Java8之前),或者不关注性能和许多不同的格式。
我经常使用Date.parse(String)来解析未知格式的日期.到目前为止,我的用例似乎工作正常,但我想知道为什么它被弃用了,我是否应该避免它?文档只是说:
As of JDK version 1.1, replaced by DateFormat.parse(String s)
但是,DateFormat中没有静态解析方法,只是一个实例方法,它需要一个DateFormat对象,对于未知的日期格式,我不会这样做.
所以,我想知道......
字符串是一个输入,我必须检查它是否是这些格式中的任何一种.如果它是sdf1格式然后传递,如果它在sdf2,3 ....然后我添加缺少格式并用sdf1格式解析它
SimpleDateFormat sdf1 = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a");
SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd/yyyy hh:mm:ssa");
SimpleDateFormat sdf3 = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
SimpleDateFormat sdf3 = new SimpleDateFormat("MM/dd/yyyy hh:mma");
SimpleDateFormat sdf3 = new SimpleDateFormat("MM/dd/yyyy hh:mm");
SimpleDateFormat sdf3 = new SimpleDateFormat("MM/dd/yyyy"); 
这就是我所拥有的
try{
            // Parse if it is MM/dd/yyyy hh:mm:ss a
            cal = Calendar.getInstance();
            cal.setTime(sdf1.parse(inStr));
          }catch(Exception exp){
             try{
               cal = Calendar.getInstance();
               //Parse if it is MM/dd/yyyy hh:mm:ssa                      
               sdf2.parse(inStr);                 
               inStr = new StringBuilder(inStr).insert(str.length()-2, " ").toString();
               cal.setTime(sdf1.parse(inStr));
              }catch(Exception dte2){
                try{
                    cal = Calendar.getInstance();
                    //Parse …java ×7
date ×3
date-format ×2
java-time ×2
jodatime ×2
control-flow ×1
datetime ×1
deprecated ×1
exception ×1
java-8 ×1
milliseconds ×1
parsing ×1
scala ×1
spring ×1
spring-mvc ×1
string ×1
try-catch ×1