如何将此格式的日期(2010 年 7 月 13 日星期二 00:00:00 CEST)转换为 Java 日期(字符串来自露天属性)tl;博士错误数据:vsWedTue java.time时区国际标准化组织 ISO 8601关于 java.time

2022-09-01 20:23:55

我正在管理一个来自Alfresco Properties的日期,并且位于指定日期(周二7月13日00:00:00 CEST 2010),我需要将其转换为Java日期...我环顾四周,发现了数百万个帖子,用于各种字符串到日期的转换形式以及此页面,所以我尝试了这样的东西:

private static final DateFormat alfrescoDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
Date dataRispostaDate = alfrescoDateFormat.parse(dataRisposta);

但它会引发异常。(例外情况是(SSollevata un'eccezione durante la gestione della data: java.text.ParseException: Unparseable date: “Tue Jul 13 00:00:00 CEST 2011”)。

我发布完整的代码:

        try {
            QName currDocTypeQName = (QName) nodeService.getType(doc);
            log.error("QName:["+currDocTypeQName.toString()+"]");
            if (currDocTypeQName != null) {
                String codAtto = AlfrescoConstants.getCodAttoFromQName(currDocTypeQName.toString());
                log.error("codAtto:["+codAtto+"]");
                if (codAtto.equals(AlfrescoConstants.COD_IQT)){
                    List<ChildAssociationRef> risposteAssociate = nodeService.getChildAssocs(doc, AlfrescoConstants.QN_RISPOSTEASSOCIATE, RegexQNamePattern.MATCH_ALL);
                    for (ChildAssociationRef childAssocRef : risposteAssociate) {
                        // Vado a prendere il nodo
                        NodeRef risposta = childAssocRef.getChildRef();
                        String dataRisposta = (nodeService.getProperty(risposta, AlfrescoConstants.QN_DATA_RISPOSTA)).toString();
                        log.error("dataRisposta:["+dataRisposta+"]");
                        if (!dataRisposta.isEmpty()){
                            try {
                                Date dataDa = dmyFormat.parse(req.getParameter("dataDa"));
                                log.error("dataDa:["+dataDa.toString()+"]");
                                Date dataA = dmyFormat.parse(req.getParameter("dataA"));
                                log.error("dataA:["+dataA.toString()+"]");
                                Date dataRispostaDate = alfrescoDateFormat.parse(dataRisposta);
                                log.error("dataRispostaDate:["+dataRispostaDate.toString()+"]");

                                if (dataRispostaDate.after(dataDa) && dataRispostaDate.before(dataA)){
                                    results.add(doc);
                                    log.error("La data risposta  è compresa tra le date specificate");
                                }else{
                                    log.error("La data risposta non è compresa tra le date specificate");
                                }
                            } catch (ParseException e) {
                                log.error("Sollevata un'eccezione durante la gestione della data: " + e);
                                throw new RuntimeException("Formato data non valido");
                            }
                        }else{
                            log.error("La data risposta non è specificata");
                        }
                    }
                }else{
                    results.add(doc);
                }
            }
        } catch (Exception e) {
            log.error("Sollevata un'eccezione durante la gestione del codice atto nel webscript nicola: " + e);
        }

任何人都可以帮忙吗?


答案 1

基本上你的问题是你使用的一个SimpleDateFormat(String pattern)构造函数,其中javadoc说:

使用给定的模式和默认区域设置的默认日期格式符号构造 SimpleDateFormat

如果您尝试使用此代码:

DateFormat osLocalizedDateFormat = new SimpleDateFormat("MMMM EEEE");
System.out.println(osLocalizedDateFormat.format(new Date()))

您会注意到,它会根据您的区域设置打印您的月份和星期几的标题。

问题的解决方案是使用 SimpleDateFormat(字符串模式,区域设置区域设置)构造函数覆盖默认的日期区域设置:

DateFormat dateFormat = new SimpleDateFormat(
            "EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
dateFormat.parse("Tue Jul 13 00:00:00 CEST 2011");
System.out.println(dateFormat.format(new Date()));

答案 2

tl;博士

ZonedDateTime.parse(                     // Produce a `java.time.ZonedDateTime` object.
    "Wed Jul 13 00:00:00 CEST 2011" ,    // Corrected `Tue` to `Wed`.
    DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss zzz uuuu" , Locale.US  ) 
)

2011-07-13T00:00+02:00[欧洲/巴黎]

错误数据:vsWedTue

您输入的字符串无效。2011年7月13日是星期三,而不是星期二Tue Jul 13 00:00:00 CEST 2011

String input = "Wed Jul 13 00:00:00 CEST 2011" ;  // Corrected `Tue` to `Wed`.

screen shot of July 2011 calendar in Duck Duck Go search engine

java.time

现代方法使用java.time类,而不是在其他Answers中看到的麻烦的旧遗留日期时间类。

定义格式设置模式以匹配输入字符串。请注意区域设置,它定义了在解析月份名称和星期几名称时使用的人类语言。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss zzz uuuu" , Locale.US  );
ZonedDateTime zdt = ZonedDateTime.parse( input , f  );

zdt.toString(): 2011-07-13T00:00+02:00[欧洲/巴黎]

时区

您的 CEST 是伪时区,而不是真正的时区。切勿使用这些。它们不是标准化的,甚至不是唯一的(!)。

该类将勇敢地猜测这样一个3-4个字符的伪区域背后的意图。你碰巧在这里工作,被解释为欧洲/巴黎时区。但你不能指望猜测是100%成功。相反,请完全避免此类伪区域ZonedDateTimeCEST

大洲/地区格式指定适当的时区名称,例如美洲/蒙特利尔非洲/卡萨布兰卡或 。Pacific/Auckland

ZoneId z = ZoneId.of( "Europe/Paris" );  // https://time.is/Paris
LocalDate today = LocalDate.now( z );  // Current date varies around the globe by zone.

国际标准化组织 ISO 8601

输入字符串的格式很糟糕。将日期时间值序列化为文本时,请仅使用标准 ISO 8601 格式。

该类通过在方括号中附加时区名称来明智地扩展标准格式,如上面的示例所示。ZonedDateTime


关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。规格是JSR 310

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过其他类扩展了 java.time。这个项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter


推荐