SimpleDateFormat("EEEE") Returns Wrong Day of Week for Timezone

Viewed 768

I have the following simple code to get the Day of week according to a timezone.

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(details.getTimezone()));
String dayOfWeek = new SimpleDateFormat("EEEE").format(calendar.get(Calendar.DAY_OF_WEEK));

Here, the details.getTimezone() returns an acceptable value such as "Asia/Kolkata" and the calendar.get(Calendar.DAY_OF_WEEK) returns the correct value 6.

According to the sequence, day 6 should return "Friday", but this function returns "Thursday" instead.

Please let me know if I am doing anything wrong.

Also let me know if I'm correct in understanding that DAY_OF_WEEK = 6 means Friday.

3 Answers

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Solution using java.time, the modern API:

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEEE", Locale.ENGLISH);
        System.out.println(dtf.format(zdt));
    }
}

Output:

Friday

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

Using legacy API:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) {
        Date date = new Date();
        DateFormat sdf = new SimpleDateFormat("EEEE", Locale.ENGLISH);
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
        System.out.println(sdf.format(date));
    }
}

Output:

Friday

* 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.

SimpleDateFormat s = new SimpleDateFormat("EEEE");

Date  date= new Date();

String dayOfTheWeek = s.format(date);

use this code for get Friday result

What went wrong in your code?

The old date and time classes from Java 1.0 and 1.1 are poorly and confusingly designed and long outdated.

Please let me know if I am doing anything wrong.

The primary thing you are doing wrong is you are using the wrong classes. Use java.time, the modern Java date and time API, as explained in the first half of the answer by Arvind Kumar Avinash.

One confusing thing about SimpleDateFormat is that it accepts formatting a number of milliseconds since the epoch (1970-01-01 at start of day in UTC) as a date. You are correct that calendar.get(Calendar.DAY_OF_WEEK) returns 6 today, and you are correct that this was supposed to mean Friday. Calendar numbers the days of the week from Sunday = 1. When you pass 6 to SimpleDateFormat.format(), it interprets 6 as 6 milliseconds past midnight in UTC on January 1, 1970. January 1, 1970, was a Thursday (and 6 milliseconds past midnight in UTC is was still only Wednesday on the Western half of the globe). Since it was Thursday in your time zone too, this is the day of week that you got.

So probably repeating myself, don’t use those old classes. Use java.time. It’s so much nicer to work with, and it is pretty much harder to make similar errors.

Link

Oracle tutorial: Date Time explaining how to use java.time.

Related