1

I have a method which generates a random date and time.

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.Period;

public String getRandomFormattedDateAndTime() {
    LocalDateTime date = generateRandomDateAndTimeInPast();
    return formatDate(date);
}
        
public LocalDateTime generateRandomDateAndTimeInPast() {
    return LocalDateTime.now()
                        .minus(Period.ofDays(
                            (new Random().nextInt(365 * 2))
                        ));
}

  public static String formatDate(LocalDateTime date) {
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT_PATTERN);
    return dateTimeFormatter.format(date);
  }

and the printed output is something like "2020-08-07T08:57:09Z"

However, i need to obtain the same value with time zone format 2020-08-07T10:57:09+02:00 which has the +02:00 (my local time).

I have seen several questions and pages like this, but they do not give me a clue.

Jeff
  • 7,767
  • 28
  • 85
  • 138
  • 3
    can't you use `ZonedDateTime`? –  May 27 '21 at 08:42
  • No, i need the `LocalDateTime ` – Jeff May 27 '21 at 08:43
  • 3
    `LocalDateTime` not have Zone part! – Youcef LAIDANI May 27 '21 at 08:45
  • 2
    I don't think you (only) need the `LocalDateTime` because it won't store any information about zone or offset and simply adding the literal `'Z'` is not a good workaround. By the way, why a `SimpleDateFormat` when there's a `DateTimeFormatter` in `java.time.format`? – deHaar May 27 '21 at 08:49
  • 2
    `DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:m:ssZ").format(date.atZone(ZoneId.systemDefault()))` or similar –  May 27 '21 at 08:51

4 Answers4

2

I hope this is what you are looking for:

ZonedDateTime  zonedDateTime = ZonedDateTime.now().minus(Period.ofDays((new Random().nextInt(365 * 2))));
System.out.println("Date Time:" + zonedDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
        

Output: Date Time:2019-07-13T14:27:51.909+05:30

Note: 05:30 is my time zone (local) offset

Dexter
  • 4,036
  • 3
  • 47
  • 55
1

In your example you're using the type LocalDateTime. LocalDateTime can't be formatted with timezone pattern as it doesn't contains any timezone information...

Switch to ZonedDateTime will solve your problem.

CodeScale
  • 3,046
  • 1
  • 12
  • 20
1

Not sure why people are involving ZonedDateTime here, but it seems to be a valid approach...

However, I want to add another one, that is the use of an OffsetDateTime.

This is an adjusted version of your method generateRandomDateAndTimeInPast:

public static OffsetDateTime generateRandomDateAndTimeInPast(int offset) {
    return OffsetDateTime.now(ZoneOffset.ofHours(offset))
                        .minusDays(
                            ThreadLocalRandom.current()
                                            .nextInt(365 * 2)
                        );
}

An example use could look like this, please note the implicit call to OffsetDateTime.toString() by directly System.outing the instance of OffsetDateTime. You can alter the output by calling OffsetDateTime.format(DateTimeFormatter).

public static void main(String[] args) {
    OffsetDateTime odt = generateRandomDateAndTimeInPast(2);
    System.out.println(odt);
}

This prints out datetimes formatted like the following (randomly generated) one:

2020-10-14T10:44:23.304+02:00

If you need a LocalDateTime (that won't contain or print any offset), you can simply get it from the OffsetDateTime like this:

LocalDateTime ldt = odt.toLocalDateTime();

A ZonedDateTime has that method, too, so if you use that or an OffsetDateTime you can always have the LocalDateTime they are based on by calling toLocalDateTime().

deHaar
  • 17,687
  • 10
  • 38
  • 51
  • @user15793316 Good point... I read this comment but could not imagine a way that prints out a `LocalDateTime` with an offset that is not hard-coded in some pattern. But I will edit the answer a little to include getting a `LocalDateTime`. – deHaar May 27 '21 at 09:15
  • Yes, @user15793316, that comment contains a handy way to achieve something that appears desired, but I am not quite sure if OP's explanations are sufficient. – deHaar May 27 '21 at 09:26
0

You have not provided the code of your method, formatDate(LocalDate). However, you have mentioned that String getRandomFormattedDateAndTime() is returning you 2020-08-07T08:57:09Z. The following method, getDateTimeInMyTz(String) provides you with what you are looking for:

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(getDateTimeInMyTz("2020-08-07T08:57:09Z"));
    }

    public static String getDateTimeInMyTz(String strDtUtc) {
        Instant instant = Instant.parse(strDtUtc);
        ZoneOffset offset = ZoneId.systemDefault().getRules().getOffset(instant);
        return instant.atOffset(offset).toString();
    }
}

Output in my timezone which has an offset of +01:00 hours:

2020-08-07T09:57:09+01:00

Usage: Replace getDateTimeInMyTz("2020-08-07T08:57:09Z") with getDateTimeInMyTz(getRandomFormattedDateAndTime()).

If you share the code of your method, formatDate(LocalDate), I can suggest further simplification.

Learn more about java.time, the modern Date-Time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • 1
    I added the code of the `formatDate()`, but your answer already worked well for me. But, i am still interested to the potential improvments. – Jeff May 27 '21 at 13:31
  • @Jeff - I am glad the solution worked for you as I expected. I can see that now you have posted the code of `formatDate` but in order to analyze the potential improvement, I need to know the value of `DATE_TIME_FORMAT_PATTERN`. By the way, I can see that you have imported `SimpleDateFormat`. I suggest you do not use `SimpleDateFormat` as it is error-prone. `DateTimeFormatter` can do all that what `SimpleDateFormat` can do, in a cleaner way. – Arvind Kumar Avinash May 27 '21 at 14:13