简体   繁体   English

在计算 Sailpoint 中用户的当前日期/时间和开始日期/时间之间的差异时出现无法解析的日期错误

[英]Getting an Unparseable date error while calculating difference between Current date/time and Start date/time for an user in Sailpoint

Getting an Unparseable date error while calculating difference between Current date/time and Start date/time for an user.在计算用户的当前日期/时间和开始日期/时间之间的差异时出现无法解析的日期错误。

Error: java.text.ParseException: Unparseable date: "09/11/20 00:00:00 AM CDT" at java.base/java.text.DateFormat.parse(DateFormat.java:395) 

I get this error at line no.8, which is我在第 8 行收到此错误,即

String output2 = sdf1.format((sdf1.parse(startDate)).getTime());

'dateDifference' is a library used to calculate the difference between the current date/time and the start date/time of an user. 'dateDifference' 是一个用于计算当前日期/时间与用户的开始日期/时间之间的差异的库。

if(link.getAttribute("lastLogonTimeStamp")== null){
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    Calendar cur_time = Calendar.getInstance();
    cur_time.setTime(new Date());
    String output = sdf.format(cur_time.getTime());
    System.out.println(" +++++ Output +++++" + output);
          
    SimpleDateFormat sdf1 = new SimpleDateFormat("MM/dd/yy HH:mm:ss a zzz");
    String output2 = sdf1.format((sdf1.parse(startDate)).getTime());
    System.out.println(" +++++ Start Date +++++" + output2);
    int diff = dateDifference(output2);
    System.out.println(" +++++ Difference +++++" + diff);
          
    if(diff>0){
        System.out.println("Start Date is not a Future Date  :" + startDate);
        bw.write(id.getName()+","+ntID+","+id.getFirstname() +" "+id.getLastname() +","+id.getEmail()+ "," + id.getAttribute("empType")+ "," +lastLoginDt+ ","+mgrName+","+(String)id.getAttribute("startDate")+","+(String)id.getAttribute("title")+"\n");
        count++;
    }
}

tl;dr tl;博士

I would not accept such a poor input string into my own app.我不会在我自己的应用程序中接受如此糟糕的输入字符串。 But if you insist, you can try to parse ambiguous input such as CDT but this is a guessing game that may fail depending on the input.但如果你坚持,你可以尝试解析有歧义的输入,比如CDT但这是一个猜谜游戏,根据输入的不同,可能会失败。

ZonedDateTime.parse(
        "09/11/20 00:00:00 AM CDT" ,
        DateTimeFormatter.ofPattern( "MM/dd/uu HH:mm:ss a z" )
)

Parsing解析

CDT is not a real time zone . CDT不是实时时区 It is a localized indicator of whether Daylight Saving Time (DST) is effect.它是夏令时 (DST)是否生效的本地化指标。

Do not use localized formats for data exchange.不要使用本地化格式进行数据交换。 Use localized values only for presentation to the user.仅将本地化值用于向用户展示。 For data exchange, use only ISO 8601 standard formats.对于数据交换,仅使用ISO 8601标准格式。 The standard was invented for just that purpose, data exchange.该标准就是为此目的而发明的,即数据交换。 The java.time classes use the standard formats by default when parsing/generating strings, so no need to specify formatting patterns. java.time类在解析/生成字符串时默认使用标准格式,因此无需指定格式模式。

Do not use Calendar and SimpleDateFormat classes.不要使用CalendarSimpleDateFormat类。 These terrible date-time classes are now legacy, years ago supplanted by the modern java.time classes defined in JSR 310. Search to learn more as this has been covered many many times already on Stack Overflow.这些糟糕的日期时间类现在已成为遗留问题,多年前被 JSR 310 中定义的现代java.time类所取代。搜索以了解更多信息,因为这已在 Stack Overflow 上多次介绍。

You can ask DateTimeFormatter class to guess what CDT might mean.您可以询问DateTimeFormatter class 来猜测CDT可能意味着什么。 But those pseudo-zone values are not standardized, and are not even unique!但是那些伪区值并不是标准化的,甚至不是唯一的! For example CST might mean "China Standard Time" or might mean "Central Standard Time" (in North America).例如, CST可能表示“中国标准时间”或可能表示“中部标准时间”(在北美)。

I recommend against accepting such poor inputs as yours, as playing guessing games in your code makes for unreliable apps.我建议不要接受像您这样糟糕的输入,因为在您的代码中玩猜谜游戏会导致应用程序不可靠。 But if you insist:但如果你坚持:

String input = "09/11/20 00:00:00 AM CDT";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uu HH:mm:ss a z" );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );

zdt.toString() = 2020-09-11T00:00-05:00[America/Chicago] zdt.toString() = 2020-09-11T00:00-05:00[美国/芝加哥]

The text generated by ZonedDateTime#toString is actually an extension to the ISO 8601 standard format, appending the name of the zone in square brackets. ZonedDateTime#toString生成的文本实际上是 ISO 8601 标准格式的扩展,将区域名称附加在方括号中。

Calculating elapsed time计算经过的时间

Apparently you want to calculate the amount of time elapsed between the moment represented by your input and the current moment.显然,您想计算输入所代表的时刻与当前时刻之间经过的时间量。

To calculate elapsed time in terms of hours-minutes-seconds, use Duration while capturing the current moment as seen in UTC (an offset from UTC of zero hours-minutes-seconds).要以小时-分钟-秒为单位计算经过的时间,请使用Duration ,同时捕获以 UTC 显示的当前时刻(与 UTC 的零小时-分钟-秒的偏移量)。

Duration elapsed = Duration.between( zdt.toInstant() , Instant.now() ) ;

To calculate elapsed time in terms of years-months-days, use Period .要根据年-月-日计算经过的时间,请使用Period Access the time zone contained in our ZonedDateTime to get the same timeframe.访问我们的ZonedDateTime中包含的时区以获得相同的时间范围。

Period elapsed = Period.between( zdt , ZonedDateTime.now( zdt.getZone() ) ; 

I have rewritten the code in the below format and that worked.我已经用下面的格式重写了代码并且有效。

if(lastLogon == null || lastLogon.equalsIgnoreCase("never")){
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    Calendar cur_time = Calendar.getInstance();
    cur_time.setTime(new Date());
    String output = sdf.format(cur_time.getTime());
              
    SimpleDateFormat dateParser = new SimpleDateFormat("MM/dd/yy HH:mm:ss a zzz");
    Date date = dateParser.parse(startDate);
    SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
    String output2 = dateFormatter.format(date);
              
    int diff = dateDifference(output2);
    if(diff>0){}

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

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