0

here is what I would like to do:

I have a date/time as a string, something like "January 2, 2010 10:25:30". The format is defined by localeLang (en, ja, unix, etc) and localeCountry (US, JP, etc). Knowing the string that represents the date and the format they are in (given by locale), I want to calculate the date/time shifted by a number of seconds.

example: date/time = January 2, 2010 10:25:30 seconds to shift = 5 result = January 2, 2010 10:25:35

Is there an easy way to do it using what Java offers ? I mean I wouldn't want to write all the logic myself, keeping in mind leap years and all those details ... :D

  • 2
    Look at the [Java 8 Date and Time](http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html) classes. You parse the string to a class, and then add the seconds. – KevinO Apr 23 '16 at 16:25
  • I suggest you make a [Gregorian Calendar](https://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html) that holds your initial time, then use the `Calendar.add()` method to add a specified time to the calendar, and the rest is handled under the hood. – MeetTitan Apr 23 '16 at 16:27
  • Does your input data include the time zone or offset-from-UTC? – Basil Bourque Apr 24 '16 at 05:21

4 Answers4

2

You could instantiate a Calendar object and use the add function. Since you already know the format of the date you will be receiving, you can instantiate a SimpleDateFormat object and pass in your format and Locale. I have a sample below that works.

    Calendar calendar = Calendar.getInstance();
    String dateStringReceived = "January 2, 2010 10:25:30";
    System.out.println("Original Date: " + dateStringReceived);
    String dateFormat = "MMMM dd, yyyy HH:mm:ss";
    SimpleDateFormat dateFormatter = new SimpleDateFormat(dateFormat, Locale.US);
    calendar.setTime(dateFormatter.parse(dateStringReceived));
    calendar.add(Calendar.SECOND, 5);
    System.out.println(dateFormatter.format(calendar.getTime()));
  • I think that's the main problem for me, that I don't know the format of the received data. It can be "January 2, 2010 10:25:30", or it can be "01/02/2010 10:25:30". However, I know the locale country and locale language. In other words, the format can be deduced from the locale. I was wondering if there is a nice solution to this without hard-coding the format ? – Catalin Demergian Apr 23 '16 at 17:10
  • Is there any sort of validation on the format? Meaning, are those 2 formats the only 2 the data might come over in? If so you can write something to first figure out the format, then parse into a Date. You would still have "hard coded" formats but you could write a formatter for both and figure out the format before you parse (i.e. you could see if the date that comes over contains the name of a month, which tells you which of the 2 from above you received). – celdridge91190 Apr 23 '16 at 17:48
  • There can be many formats, maybe 20, like described in here: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html. I was thinking that having the locale country & language (which I know, they come as parameters) I can initialize some object that knows what the format should be and from that point on I can use the date.plus Java function. – Catalin Demergian Apr 24 '16 at 08:56
  • You will need some way to figure out what the format is before you start your function. I recommend using Calendar rather than Date as most of the functions in Date are deprecated at this point and Calendar is more the new standard. – celdridge91190 Apr 25 '16 at 14:21
2

The easiest way is to parse the string to a LocalDateTime object:

String input = "January 2, 2010 10:25:30";
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("MMMM d, yyyy HH:mm:ss", Locale.ENGLISH);
LocalDateTime date = LocalDateTime.parse(input, fmt);

and then add 5 seconds:

LocalDateTime result = date.plus(5, ChronoUnit.SECONDS);
assylias
  • 321,522
  • 82
  • 660
  • 783
  • The better approach since it does not rely upon outdated and problematic date and time classes. – KevinO Apr 23 '16 at 17:01
1

java.time

The java.time framework is built into Java 8 and later. These classes supplant the old troublesome classes such as java.util.Date/.Calendar. And these classes supplant the highly successful Joda-Time library.

Get the current moment on the timeline in UTC.

Instant instant = Instant.now();

Apply a time zone.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

Add 5 seconds. The "plus…" methods handle issues such as leap year, Daylight Saving Time, and other anomalies.

ZonedDateTime zdtLater = zdt.plusSeconds( 5 );

Use your language and country codes to determine a Locale object.

Locale locale = new Locale( "fr" , "CA" );  // French, Canada (Québec)

Generate string. Let the formatter automatically localize per the Locale, translating to a human language like French and using cultural formatting norms (order of elements, comma versus period, etc.) such as in Québec Canada.

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL );
formatter = formatter.withLocale( locale );
String string = zdtLater.format( formatter );

Going the other direction. But try to avoid this direction. Localized strings of a date-time should be for display to the user, not for data-exchange.

ZonedDateTime zdtNew = ZonedDateTime.parse( string , formatter );
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • great answer! this is what I meant by parsing date/time without hard-coding on a specific format and use only locale parameters. thank you! – Catalin Demergian Apr 24 '16 at 17:17
0

Solution #1

Parse the String to a date (How to parse date string to Date?), then add the 5 seconds, and make the date to string (with the same SimpleDateFormat object)

Solution #2

Split the string into all components, and add 5 to the last component (that should be the "seconds" component). If the result is greater than 60, add 1 to the "minutes" component and join the components so they match the old format

Community
  • 1
  • 1
SEUH
  • 314
  • 3
  • 15
  • Your solution #1 is right, but your solution #2 is so awfully bad, it is a reason for downvote. The OP already anticipated this and explicitly stated that he does not want to do that. – Mike Nakis Apr 23 '16 at 16:43
  • @MikeNakis Solution #2 is right. It needs some logic but there's nothing wrong. Yes, OP said he don't want to do this logic, therefore my answer has solution #1. Why are you complaining on extra information? And if someone says that he doesn't want to do logic, doesn't mean that you aren't allowed to write logic concepts – SEUH Apr 23 '16 at 16:51