【问题标题】:How to convert a date in this format (Tue Jul 13 00:00:00 CEST 2010) to a Java Date (The string comes from an alfresco property)如何将此格式的日期(Tue Jul 13 00:00:00 CEST 2010)转换为 Java 日期(字符串来自 alfresco 属性)
【发布时间】:2011-08-21 16:13:15
【问题描述】:

我正在管理一个来自 Alfresco Properties 并且在指定日期(2010 年 7 月 13 日星期二 00:00:00 CEST)的日期,我需要将其转换为 Java 日期...我环顾四周并找到了数百万条关于各种字符串到日期转换表格的帖子以及this page,所以我尝试了这样的事情:

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

有人可以帮忙吗?

【问题讨论】:

  • 你能扩展“它不起作用”吗?会发生什么?
  • @Nicola 假设“log”是 log4j 或 java.util.logging,将 catch 块中的行更改为: log.error(""Sollevata un'eccezione durante la gestione del codice atto nel webscript nicola", e);
  • 其定义如下: Data rispostad:date 你的意思是这个应该管用?日期数据Risposta = (Date)(nodeService.getProperty(risposta, AlfrescoConstants.QN_DATA_RISPOSTA));
  • @Gagravarr 你是对的,它有效!如果你回答这个帖子,我会将你的答案标记为已接受。
  • 仅供参考,麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 和 Java 中内置的 java.time 类所取代9. 见Tutorial by Oracle

标签: java alfresco date-parsing


【解决方案1】:

基本上你的问题是你正在使用SimpleDateFormat(String pattern)构造函数,javadoc说:

构造一个 SimpleDateFormat 使用 给定的模式和默认日期 默认语言环境的格式符号。

如果您尝试使用此代码:

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

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

您的问题的解决方案是使用SimpleDateFormat(String pattern, Locale locale) 构造函数覆盖默认日期语言环境:

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

【讨论】:

  • 这很有意义。 @Nicola,您的默认语言环境是意大利语吗?
  • 是的。我认为这是一个非常好的建议。我已将另一个标记为答案,因为我的问题是“Alfresco 相关”,而另一个答案在我的情况下要干净得多,但感谢您的回答!
  • 仅供参考,麻烦的旧日期时间类,例如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 和 Java 中内置的 java.time 类所取代9. 见Tutorial by Oracle
  • IDK 这段代码发生了什么,我只想将我输入的 2019/05/05 保存在数据库中作为 2019/05/05。但是在运行解析日期保存的内容时,我收到的格式类似于“Tue Jul 13 00:00:00 CEST 2011”,但保存在数据库中的是 2019/05/05。我很困惑为什么我知道应该保存的实际值与保存在数据库中的值不同,或者是否存在一些隐藏的过程?无论如何,现在我的日期现在解析正确,太好了。谢谢..
【解决方案2】:

根据您的 cmets,我相信您的属性实际上是 d:dated:datetime 类型。如果是这样,该属性将已经作为 java Date 对象从 Alfresco 返回。所以,你需要做的就是:

  NodeRef risposta = childAssocRef.getChildRef();
  Date dataRisposta = (Date)nodeService.getProperty(risposta, AlfrescoConstants.QN_DATA_RISPOSTA);

【讨论】:

    【解决方案3】:

    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[欧洲/巴黎]

    错误数据:Wed vs Tue

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

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

    java.time

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

    定义格式模式以匹配您的输入字符串。注意Locale,它定义了用于解析月份名称和星期名称的人类语言。

    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 是一个伪时区,而不是真正的时区。永远不要使用这些。它们不是标准化的,甚至不是唯一的(!)。

    ZonedDateTime 类将努力猜测这样一个 3-4 个字符的伪区域背后的意图。您的CEST 恰好在这里工作,解释为Europe/Paris 时区。但是你不能相信猜测是 100% 成功的。相反,完全避免此类伪区域

    continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/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 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

    从哪里获得 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      【解决方案4】:

      问题在于 CEST 不是 Java 支持的时区。您可以使用“CST”。

      TimeZone 注释的 Javadoc:

      三个字母的时区 ID 为了与 JDK 1.1.x 兼容,还支持一些其他的三字母时区 ID(例如“PST”、“CTT”、“AST”)。但是,不推荐使用它们,因为相同的缩写通常用于多个时区(例如,“CST”可能是美国“中部标准时间”和“中国标准时间”),而 Java然后平台只能识别其中之一。

      对于三/四个字母时区支持,我建议您尝试 JodaTime,它可能会做得更好。


      String dataRisposta = "Tue Jul 13 00:00:00 CST 2010";
      Date dataRispostaDate = alfrescoDateFormat.parse(dataRisposta);
      System.out.println(dataRispostaDate);
      

      打印

      Tue Jul 13 07:00:00 BST 2010
      

      String[] ids = TimeZone.getAvailableIDs();
      Arrays.sort(ids);
      for (String id : ids) {
          System.out.println(id);
      }
      

      打印

      ...
      CAT
      CET
      CNT
      CST
      CST6CDT
      CTT
      ...
      

      【讨论】:

      • 问题是字符串是露天节点的属性。我接受它: String dataRisposta = (nodeService.getProperty(risposta, AlfrescoConstants.QN_DATA_RISPOSTA)).toString();
      • 它不会对我抛出异常。如果您知道您希望 CEST 表示 CST 或其他时区,您可以使用 .replaceAll("CEST", "CST")
      • 我不认为这个答案是正确的。 SimpleDateFormat (download.oracle.com/javase/6/docs/api/java/text/…) 的规范说“对于解析,也接受 RFC 822 时区”。这些是 4 个字母的时区;我认为 CEST 就是其中之一。当我运行该示例时,它运行良好,没有抱怨时区格式,并返回了合理的结果。
      • 更新不起作用,但它使用以下行起作用: Date dataRisposta = (Date)(nodeService.getProperty(risposta, AlfrescoConstants.QN_DATA_RISPOSTA));
      • 仅供参考,Joda-Time 项目现在位于maintenance mode,团队建议迁移到java.time 类。见Tutorial by Oracle
      【解决方案5】:

      试试这个功能我遇到了同样的问题。

      public String getMyDate(String myDate, String requiredFormat, String mycurrentFormat) {
          DateFormat dateFormat = new SimpleDateFormat(returnFormat);
          Date date = null;
          String returnValue = "";
          try {
              date = new SimpleDateFormat(myFormat, Locale.ENGLISH).parse(myDate);
              returnValue = dateFormat.format(date);
          } catch (ParseException e) {
              returnValue = myDate;
          }
          return returnValue;
      }
      

      例子:

      2020 年 5 月 6 日星期三 13:01:29 EDT 即“EEE MMM dd HH:mm:ss zzz yyyy”是 mycurrentFormat

      4.May.2020 即“d.MMM.yyyy”是我需要的格式

      Date date = new Date();
      
      getMyDate(date.toString(), "d.MMM.yyyy", "EEE MMM dd HH:mm:ss zzz yyyy")
      

      【讨论】:

      • 请不要教年轻人使用早已过时且臭名昭著的SimpleDateFormat类。至少不是第一选择。而且不是没有任何保留。今天我们在java.time, the modern Java date and time API, 和它的DateTimeFormatter 中有很多更好的东西。此外,您的代码比大多数其他答案中的代码长。它比那些有什么优势吗?
      猜你喜欢
      • 2018-03-23
      • 1970-01-01
      • 2021-03-25
      • 1970-01-01
      • 1970-01-01
      • 2021-03-30
      • 2020-08-04
      • 2022-01-10
      • 2023-03-07
      相关资源
      最近更新 更多