-2

I have a string with value "25/12/2021" and I want to convert this string into a date format which has a New York timezone.

I am new to Java dates

I tried the below:

SimpleDateFormat zdate = new SimpleDateFormat("dd/MM/yyyy");
zdate.setTimeZone(TimeZone.getTimeZone("America/New_York"));

Date zdate2 = zdate.parse("25/12/2021")

but the zdate2 object has the date in my local timezone rather than the New_York timezone.

What am I doing wrong here?

Mortifer
  • 3
  • 3
  • 4
    Is there a reason you're using the outdated date classes instead of the newer, more feature-rich classes from the `java.time` package, such as `LocalDate`? – E-Riz Feb 16 '23 at 14:12
  • 1
    You input - `25/12/2021` contains no time, only a date. So are we assuming `25/12/2021 00:00` UTC? – Chaosfire Feb 16 '23 at 14:15
  • 2
    Typo: `dd/MM/yyy` should be `dd/MM/yyyy`. And, yes, please avoid `Date` and `SimpleDateFormat`. – andrewJames Feb 16 '23 at 14:17
  • 1
    I strongly recommend that you don’t touch `SimpleDateFormat`, `TimeZone` and `Date`. Those classes are poorly designed and long outdated, the first in particular notoriously troublesome. Use [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/index.html). See [the answer by deHaar](https://stackoverflow.com/a/75473651/5772882). – Ole V.V. Feb 16 '23 at 19:28

3 Answers3

2

If you are not forced to use java.util.Date, which itself does not have any zone, you could have your requirement met by implementing with java.time:

You just have to

  • parse it to a LocalDate, a class only having year, month of year and day of month
  • append a time of day
  • append the zone

Here's an example…

public static void main(String[] args) throws ParseException {
    // example input
    String input = "25/12/2021";
    // create a pattern handler for parsing
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/uuuu");
    // create the zone
    ZoneId americaNewYork = ZoneId.of("America/New_York");
    // parse the String to a LocalDate, then add time of day and zone
    ZonedDateTime result = LocalDate.parse(input, dtf)
                                    .atStartOfDay(americaNewYork);
    System.out.println(result);
}

Output:

2021-12-25T00:00-05:00[America/New_York]
deHaar
  • 17,687
  • 10
  • 38
  • 51
  • Actually I am connecting to an old api which accepts only java.util.Date as an argument. Can Passing LocaleDate cause any issue in such case? – Mortifer Feb 16 '23 at 14:33
  • There are methods for legacy compatibility, but you cannot use them with a plain `LocalDate`, you will have to provide a time of day and a zone or offset from utc, too. What are you doing with this API? Are you only receiving `Date`s or do you intend to send anything to the API? – deHaar Feb 16 '23 at 14:48
  • The most important thing here is to understand that a `Date` does not have any zone. It is basically a wrapper around epoch milliseconds. There`s an equivalent in `java.time` with the (more suitable) name `Instant`. You can convert a `ZonedDateTime` to an `Instant` and use `Date.from(Instant)` or `Date.toInstant()` in order to establish compatibility with legacy code. – deHaar Feb 16 '23 at 14:51
  • 1
    The Api basically accepted 2 parameters of java.util.date and returned some data for that date range. And it required date in New York time zone to as to send back the relevant data that i need. I tried using `Instant` and this worked. As you suggested, What I did basically was create a ZonedDateTime, converted it to Instant and used `Date.from(Instant)` and got the date that I wanted. So thanks a lot for the solution. I'll mark your response as the accepted answer. :) – Mortifer Feb 16 '23 at 17:09
  • 1
    `Date zonedDate = Date.from(result.toInstant());` Added this post following the Answer by deHaar – Mortifer Feb 16 '23 at 17:19
0

Small protest about parse() on time objects, the following is what it really takes to assure creation from String information that parse() methods continually reject !!!

bash-5.1$ javac ZoneParse.java

Note: ZoneParse.java uses or overrides a deprecated API.

Note: Recompile with -Xlint:deprecation for details.

bash-5.1$ java ZoneParse

24 Dec 2021 13:00:00 GMT

bash-5.1$

It will be something alike the following if safe...

import java.time.*;

public class ZoneParse{

public ZoneParse(){
String[] dt = ("25/12/2021").split("/");
ZonedDateTime ztm = (LocalDate.of(new Integer(dt[2]).intValue(),new Integer(dt[1]).intValue(),new Integer(dt[0]).intValue())).atStartOfDay(ZoneId.systemDefault());
System.out.println((java.util.Date.from(  (ztm.withZoneSameInstant((ZoneId)ZoneId.of("America/New_York")).toInstant()))).toGMTString());
}//enconstr

public static void main(String[] args){
new ZoneParse();
}//enmain

}//enclss

NOTE withZoneSameInstant() changes both the time and the zone.

withZoneSameLocal() only retags the time as belonging as another time zone

The updated time library since around java 8 is quicker This following link is a library with some time assistance under construction avoids parse() as much as possible including a pair of methods of String fill in arguments to create a timedate. https://drive.google.com/file/d/1gjHmdC-BW0Q2vXiQYmp1rzPU497sybNy/view?usp=share_link

The below erroneous code is because parse() is probably one of the WORST explained methods in the docs, it generally requires a few different pages each of different sections to get any explanation of how to use it. ZonedDateTime ztm = ZonedDateTime.parse("25/12/2021"); Instant it = (ztm.withZoneSameInstant((ZoneId)ZoneId.of("America/New_York"))).toInstant(); java.util.Date date = java.util.Date.from(it);

Samuel Marchant
  • 331
  • 2
  • 6
  • A sympathetic attempt. It gives *java.time.format.DateTimeParseException: Text '25/12/2021' could not be parsed at index 0*. :-( – Ole V.V. Feb 16 '23 at 19:24
  • I hate to say it, parse() on any of the time objects could well be something to remove from the APIs , it consume too much time by wasting time to get it to operate. – Samuel Marchant Feb 18 '23 at 07:46
-1
SimpleDateFormat zdate = new SimpleDateFormat("dd/MM/yyyy");
zdate.setTimeZone(TimeZone.getTimeZone("America/New_York"));

Date zdate2 = zdate.parse("25/12/2021")

Remember the four 'y' letters in format

  • 1
    Yeah, that was a typo. corrected the question – Mortifer Feb 16 '23 at 17:21
  • 1
    This does not answer the question. `SimpleDateFormat` would ignore the number of letters for parsing. Yes, its confusing and unsafe. I said don’t use that class. – Ole V.V. Feb 17 '23 at 06:34