简体   繁体   中英

Error when I try to change my time/date to UTC-1

I have a Date with the actual time of my system (I live in Spain). I need to change it to UTC-1, but it doesn't matter if I write "UTC-1" or "UTC-2", it always gives me the same time less 2 hours, I mean:

My system hour (time_utc): 11:00 13/04/2021 Try UTC-1 (time): 09:00 13/04/21 Try UTC-2 (time): 09:00 13/04/21

I have this code:

    Date time_utc = new Date();
    DateFormat convertidor = new SimpleDateFormat("yyyy-MM-dd HH:00:00.000");    
    
    convertidor.setTimeZone(TimeZone.getTimeZone("UTC-1"));     

    time = convertidor.format(time_utc);    

Why it doesn't work? Can anyone helps me? Thanks a lot!

¡Hola!

You can do that in a pretty short way using java.time ( if you are allowed and willing to do so ).

There are special classes that represent a moment in time in different time zones of offsets. One of them is an OffsetDateTime , see this example:

public class Main {

    public static void main(String[] args) {
        // create one of your example date times in UTC
        OffsetDateTime utcOdt = OffsetDateTime.of(2021, 4, 13, 11, 0, 0, 0, ZoneOffset.UTC);
        // and print it
        System.out.println(utcOdt);
        /*
         * then create another OffsetDateTime 
         * representing the very same instant in a different offset
         */
        OffsetDateTime utcPlusTwoOdt = utcOdt.withOffsetSameInstant(ZoneOffset.ofHours(2));
        // and print it
        System.out.println(utcPlusTwoOdt);
        // do that again to see "the other side" of UTC (minus one hour)
        OffsetDateTime utcMinusOneOdt = utcOdt.withOffsetSameInstant(ZoneOffset.ofHours(-1));
        // and print that, too.
        System.out.println(utcMinusOneOdt);
    }
}

It outputs the following three lines:

2021-04-13T11:00Z
2021-04-13T13:00+02:00
2021-04-13T10:00-01:00

As you can see, the time of day is adjusted according to the offset.

The output could be formatted in your desired style if needed (this currently just uses the toString() method of OffsetDateTime ).

UPDATE

You can achieve the output formatted as desired by defining the pattern as uuuu-MM-dd HH:mm when using a java.time.format.DateTimeFormatter .
Just add the following lines to the example above:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm");

System.out.println(utcOdt.format(dtf));
System.out.println(utcPlusTwoOdt.format(dtf));
System.out.println(utcMinusOneOdt.format(dtf));

This would then output

2021-04-13 11:00
2021-04-13 13:00
2021-04-13 10:00

And if you really want fix zeros for seconds and millis, then create your DateTimeFormatter like this:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:00.000");

which will cause output like this:

2021-04-13 11:00:00.000
2021-04-13 13:00:00.000
2021-04-13 10:00:00.000

As a supplement to the good answer by deHaar:

  1. As Matt Johnson-Pint already asked, do you need to convert to a different time zone? This would be the most typical. If so, use that time zone, not just a UTC offset of -1. By all probability that time zone has used other offsets in the past and may well do so in the future. So -01:00 isn't safe. A real time zone ID like Atlantic/Cape_Verde is safer.
  2. You don't need to go through the current time in your own time zone and convert. java.time can directly give you the current time in another time zone or at a specific UTC offset.
  3. java.time can also truncate a time to whole hours.

So for example:

    DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS");
    
    ZoneId zone = ZoneId.of("Atlantic/Cape_Verde");
    ZonedDateTime nowInCaboVerde = ZonedDateTime.now(zone);
    
    System.out.println(nowInCaboVerde);
    System.out.println(nowInCaboVerde.truncatedTo(ChronoUnit.HOURS)
            .format(formatter));

Output:

 2021-04-14T03:12:28.272010-01:00[Atlantic/Cape_Verde] 2021-04-14 03:00:00.000

PS Cabo Verde/Cape Verde was at offset -02:00 until 1975.

What went wrong in your code?

This is how confusingly the old TimeZone class behaves and one of the reasons why you should never use it: When given a time zone ID that it does not recognize, it returns GMT and pretends all is well. UTC-1 is not a recognized time zone ID. In case it didn't make sense to refer to a real time zone and you needed the offset -01:00 from UTC, you might have used GMT-1 or GMT-01:00 . Yes, TimeZone refers to UTC as GMT even though they are not strictly speaking the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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