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 Date-Time API:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Note: If you want to work with a specific timezone, use LocalDate.now(ZoneId)
// e.g. LocalDate.now(ZoneId.of("Australia/Brisbane")) or
// LocalDate.now(ZoneOffset.UTC) etc.
LocalDate today = LocalDate.now();
int doy = today.getDayOfYear();
System.out.println(doy);
// Using DateTimeFormatter (not recommended for production code)
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("D", Locale.ENGLISH);
String strDoy = today.format(dtf);
System.out.println(strDoy);
}
}
Output in my timezone, Europe/London:
289
289
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
For any reason, if you want to use the legacy API:
A java.util.Date object simply represents an instant on the timeline — a wrapper around the number of milliseconds since the UNIX epoch (January 1, 1970, 00:00:00 GMT). Since it does not hold any timezone information, its toString function applies the JVM's timezone to return a String in the format, EEE MMM dd HH:mm:ss zzz yyyy, derived from this milliseconds value. To get the String representation of the java.util.Date object in a different format and timezone, you need to use SimpleDateFormat with the desired format and the applicable timezone e.g.
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String strDateNewYork = sdf.format(date);
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String strDateUtc = sdf.format(date);
Let's see why knowing the above fact is important:
The function, Calendar#getInstance returns a calendar based on the current time in the default time zone with the default FORMAT locale. If you want to find some information from it for some other timezone, you have two options:
- Change the default timezone e.g.
TimeZone.setDefault(TimeZone.getTimeZone("Australia/Brisbane")). However, this may result in other parts of the application behave incorrectly. Therefore, this option is strongly discouraged.
- Format the
java.util.Date (which you can get via Calendar#getTime) using SimpleDateFormat set with the required timezone shown above.
Demo:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("D");
// For the JVM's timezone
sdf.setTimeZone(TimeZone.getDefault());
System.out.println(sdf.format(now));
// For the timezone, UTC
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(now));
// For the timezone, Australia/Brisbane
sdf.setTimeZone(TimeZone.getTimeZone("Australia/Brisbane"));
System.out.println(sdf.format(now));
System.out.println();
}
}
Output in my timezone, Europe/London at the time of posting this answer:
289
289
290
ONLINE DEMO
* 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. Note that Android 8.0 Oreo already provides support for java.time.