【问题标题】:Format Date from string in one format back to string then parse string to date将日期从一种格式的字符串格式化回字符串,然后将字符串解析为日期
【发布时间】:2022-02-01 08:04:24
【问题描述】:

我试图用 ("MM/dd/yyyy") 抓取一个字符串(日期)解析,然后用 (“EEE MMM dd kk:mm:ss z yyyy”)然后再次解析该字符串,创建格式为(“EEE MMM dd kk:mm:ss z yyyy”)的日期。所以我可以比较两个日期的格式(“EEE MMM dd kk:mm:ss z yyyy”)

没有得到任何解析错误,但我试图用它来比较两个日期。遇到无法创建列表的问题,因为我的比较不起作用。在这种类型的转换方面需要一点帮助

                  private Date getDateNDaysAgo(int numDays) {
                  log.debug("getDateNDaysAgo 1 " + numDays);
                  Calendar cal = Calendar.getInstance();
                  Date returnDate = null;
                  cal.add(Calendar.DATE, -(numDays));
                  returnDate = cal.getTime();
                  log.debug("getDateNDaysAgo 2" + returnDate);
                  return (returnDate);
                  }                 

              String EffectiveHireString = null;
              String EffectiveHireDate = null;
              
              
              Date returnEffectiveHireDate = null;
              Date thresholdDate = null;
              Date newEffectiveHireDate=null;
              boolean isAccountCreatedOver25Days = false; 

              link = (Link)itrLinkResults.next();

              // only pull active accounts
              if(!link.isDisabled()) {
              if(link.getAttribute("lastLogon") != null){
              log.debug("QueryParameter: lastLogon (1): not null");
              lastLogon = link.getAttribute("lastLogon");
              }

              if(link.getAttribute("EffectiveHireDate") != null){
              log.debug("QueryParameter: EffectiveHireDate (1): not null");
              acuEffectiveHireDate  = link.getAttribute("EffectiveHireDate");

              if(Util.isNotNullOrEmpty(EffectiveHireDate)) {

              DateFormat df = new SimpleDateFormat("EEE MMM dd kk:mm:ss z yyyy"); 
              SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
              SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd kk:mm:ss z yyyy");
              try {
                  
                newEffectiveHireDate = sdf.parse(EffectiveHireDate);
                EffectiveHireString = df.format(newEffectiveHireDate);
                returnEffectiveHireDate = formatter.parse(EffectiveHireString);
                
                thresholdDate = getDateNDaysAgo(25);
                log.debug("thresholdDate" + thresholdDate);

               if(returnEffectiveHireDate.compareTo(thresholdDate) < 0){
              log.debug("returnEffectiveHireDate 2" + returnEffectiveHireDate);
              isAccountCreatedOver25Days = true;** 
              }
              }
                  catch (ParseException e) {
                  log.error("Error attempting to parse EffectiveHireDate Date");
                  }
                  }
                  }

【问题讨论】:

  • 但我试图用它来比较两个日期。如果你能解释比较标准会很有帮助。另外,您说比较日期,但您的格式包含时间元素。
  • 您的问题令人费解且令人困惑。为清楚起见重写。提示: (a) 切勿使用Date/Calendar/DateFormat。几年前,它们被 java.time 类所取代。 (b) 不要为解析生成本地化字符串。仅使用标准 ISO 8601 格式进行数据交换。 java.time 类默认使用标准格式来生成/解析字符串。 (c) 在此处发布代码时,将其精简到显示您的问题所需的最低限度。
  • 我正在比较日期/时间以查看用户是否在 25 天内登录系统。这些是我必须使用的类。
  • 我遇到了字符串到日期解析的问题 - 格式化为字符串然后解析回日期。
  • 你说“这些是我必须使用的类。”为什么?您使用的是非常旧的 Java 版本吗?你在安卓上吗? (有适用于 Android 的 java.time API 版本。)

标签: java date


【解决方案1】:

您尝试执行的操作存在概念问题。您正在获取格式为 MM/dd/yyyy 的日期并将其转换为具有日期、时间和时区的字符串表示形式,但您的初始数据仅包含日期,而不包含时间或时区。当然,您可以将时间设置为 00:00:00,将时区设置为系统默认值,但这些假设可能不正确。

无论如何,您可以使用 java.time API 做到这一点:

import java.time.*;
import java.time.format.*;

// . . .

    DateTimeFormatter mdy = DateTimeFormatter.ofPattern("MM/dd/yyyy");
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd kk:mm:ss z yyyy");
    String date = "01/28/2022";
    
    // the follow steps could be combined, but they are separated for clarity
    LocalDate localDate = mdy.parse(date, LocalDate::from);
    LocalDateTime ldt = LocalDateTime.of(localDate, LocalTime.of(0, 0));
    ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault);
    
    // formatted as "Fri Jan 28 24:00:00 EST 2022"
    String formatted = formatter.format(zdt);
    ZonedDateTime parsed = formatter.parse(formatted, ZonedDateTime::from);
    // parsed.equals(zdt) == true
    // parsed.compareTo(zdt) == 0

如果您真的只是想比较日期,我强烈建议您只使用 LocalDate 类,完全不考虑时间和时区。

这是一个仅使用日期、日历和(简单)日期格式的示例:

boolean checkEffectiveHireDate(String hireDateMMddyyyy) throws ParseException {
    DateFormat mmddyyyy = new SimpleDateFormat("MM/dd/yyyy");
    DateFormat fullFormat = new SimpleDateFormat("EEE MMM dd kk:mm:ss z yyyy");
    Date hireDate = mmddyyyy.parse(hireDateMMddyyyy);
    String effectiveHire = fullFormat.format(hireDate);
    System.out.println(effectiveHire);
    Date effectiveHireDate = fullFormat.parse(effectiveHire);
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.DATE, -25);
    Date thresholdDate = cal.getTime();
    return effectiveHireDate.compareTo(thresholdDate) < 0;
}

【讨论】:

  • 感谢您的支持。时区(如果需要)。我会测试输出
  • 我在尝试使用相同的日期格式时仍然遇到解析错误
  • @nmeagher 我刚刚尝试使用 Calendar、Date 和 SimpleDateFormat,但没有收到任何错误。你得到什么错误?它无法解析的字符串是什么?您使用的是什么版本的 Java?
  • @nmeagher 我刚刚添加的checkEffectiveHireDate"01/20/2022"true 返回false"01/02/2022" 并且在任何一种情况下都不会抛出ParseException。我正在使用 JDK 18 的早期访问版本,但我也尝试使用 JDK 11.0.9 和 JDK 1.8.0_311。
  • 我胖手指了一个丢失的右括号。使用日期、日历和(简单)日期格式有效。感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 2021-07-27
  • 1970-01-01
  • 1970-01-01
  • 2011-12-14
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
  • 1970-01-01
相关资源
最近更新 更多