0

I am facing an issue while saving date more then 2038 years in my application, At jsp page I am getting input from calendar like -

registry.byId('endDateCal').set('value', dojo.date.locale.parse('<c:out value="${empty taskForm.endDate ? taskForm.defaultDate : taskForm.endDate}"/>', {     datePattern: '<%=datePattern%>',     selector: "date"   }));

datePattern I am setting on my jsp page globlly like

   SimpleDateFormat dateFormat = (SimpleDateFormat)DateFormat.getDateInstance(DateFormat.SHORT, I18nUtility.getLanguageLocaleForCurrentUser());

   String datePattern = dateFormat.toPattern();

while this value is sending to my servlet I am getting value in past for example if I will set date 9/30/2040 then it will send date value to servlet 9/30/1941.

I saw the 2038 problem Year 2038 problem but it is not in my case, because i am able to set date in 2038, but wont be able to set more then 2038, I also check with this but didn't help.

Note looking for jdk 7 compatible solution

Afgan
  • 1,022
  • 10
  • 32
  • Are you sure it is broken on the Java side of things (and not in the Javascript code)? – Thilo Sep 05 '19 at 08:51
  • 2
    ..and do you claim that you can safely set dates `after 03:14:07 UTC on 19 January 2038`? – Kayaman Sep 05 '19 at 08:52
  • Is it properly receveid by the client before send to the servlet ? – AxelH Sep 05 '19 at 08:52
  • 2
    80/20 rule. *For parsing with the abbreviated year pattern ("y" or "yy"), SimpleDateFormat must interpret the abbreviated year relative to some century. It does this by adjusting dates to be within 80 years before and 20 years after the time the SimpleDateFormat instance is created. For example, using a pattern of "MM/dd/yy" and a SimpleDateFormat instance created on Jan 1, 1997, the string "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64" would be interpreted as May 4, 1964.* [from the docs](https://docs.oracle.com/javase/10/docs/api/java/text/SimpleDateFormat.html). – Ole V.V. Sep 05 '19 at 08:55
  • But you should avoid the notoriously troublesome and long outdated `DateFormat` and `SimpleDateFormat` if you can. – Ole V.V. Sep 05 '19 at 08:55
  • @AxelH yes it is properly receveid by the client, – Afgan Sep 05 '19 at 09:19
  • @Kayaman yes I can able to set date after 03:14:07 UTC on 19 January 2038 – Afgan Sep 05 '19 at 09:19
  • @OleV.V. Thanks for you input, it seems me convincing to me, but need more elaboration and work around/ fix for same issue. And Yes, I cant avoid utdated DateFormat and SimpleDateFormat. – Afgan Sep 05 '19 at 09:21
  • 2
    In SimpleDateFormat, you can set a startdate to determine how 2-digit-years are interpreted. See https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html#set2DigitYearStart(java.util.Date) – Erich Kitzmueller Sep 05 '19 at 09:33

1 Answers1

3

tl;dr

LocalDate                                    // Modern class for representing a date-only value without time-of-day and without time zone.
.parse(
    "1/23/40" , 
    DateTimeFormatter.ofPattern( "M/d/uu" )  // Defaults to century 20xx. 
)                                            // Returns a `LocalDate` object.
.toString()                                  // Generate text in standard ISO 8601 format.

2040-01-23

Specify default century

The SimpleDateFormat class has a setting for what century to assume when parsing an input string with a two-digit century: SimpleDateFormat::set2DigitYearStart.

But… you should stop using this class.

java.time

That SimpleDateFormat class is part of the terrible date-time classes bundled with the earliest versions of Java. These classes are now legacy, supplanted entirely by the modern java.time classes defined in JSR 310.

LocalDate

The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.

➥ This class parses input strings with two-digit years always using the century of 20xx.

String input = "1/23/40" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/d/uu" ) ;
LocalDate localDate = LocalDate.parse( input , f ) ;

See this code run live at IdeOne.com.

localDate.toString(): 2040-01-23

Tip: I have found the use of 2-digit years to be quite troublesome in business apps. The ambiguity with day-of-month and month makes it easy for misinterpretation and miscommunication. I suggest always using 4-digit years.

This problem is even worse when sharing data across cultures. Then I suggest using ISO 8601 formats for textual date-time values.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Thanks for answer, This fix can only applicable for jdk8(java.time.*) or above and it is not applicable for jdk7 and below, as we have our application which are using older version of java, can you please suggest solution for jdk7 and lower version – Afgan Sep 10 '19 at 16:56
  • 2
    @Afgan See the "About java.time" section I added at the end. Adding the *ThreeTen-Backport* library to your project is definitely worth the bother. Never use `Date`/`Calendar` etc., they really are that bad. – Basil Bourque Sep 10 '19 at 20:26