Please help me to format properly my String.
I really need to display "10 November 2015" instead of 10/11/2015
Calendar now = Calendar.getInstance();
now.add(Calendar.MONTH, 10);
textView1.setText(("date after 10 months : " + (now.get(Calendar.MONTH) + 1) + "-"
+ now.get(Calendar.DATE) + "-" + now.get(Calendar.YEAR)));
System.out.println(new SimpleDateFormat("dd MMMM yyyy", Locale.ENGLISH)
.format(new java.util.Date()));
Always stay on the safer size specify the Locale.
Use SimleDateFormat as given by other. Use the below string to get desired output.
SimpleDateFormat format = new SimpleDateFormat("dd MMMM yyyy")
use new SimpleDateFormat("dd MMMM yyyy")Read more about SimpleDateFormat
here you can use this function:-
public static void main(String[] args) throws ParseException {
System.out.println(new SimpleDateFormat("dd MMMM yyyy").parse("10/11/2015"));
}
tl;dr
Apparently you want to get the current date as seen in the wall-clock time used by the people of a particular region, add ten months, and then generate text representing the value of that found date.
LocalDate.now(
ZoneId.of( "Pacific/Auckland" )
)
.plus(
Period.ofMonths( 10 )
)
.format(
DateTimeFormatter.ofLocalizedDate( FormatStyle.LONG )
.withLocale( Locale.ITALY )
)
java.time
The modern approach uses the java.time classes that supplanted the terrible Date & Calendar classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your [desired/expected time zone][2] explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Adding to a date
Define the span-of-time you want to add.
Period p = Period.ofMonths( 10 ) ; // Ten months span, unattached to timeline.
Add the period to our LocalDate to get another LocalDate. As an immutable object, LocalDate produces a new instance based on the values of the original object.
LocalDate later = ld.plus( p ) ;
Generating text
To generate text in standard ISO 8601 format, call toString.
String output = later.toString() ;
To generate text in a String representing the value of our LocalDate, use the DateTimeFormatter class.
Generally best to let java.time automatically localize by calling the DateTimeFormatter.ofLocalized… methods.
To hard-code a specific format, specify a formatting pattern.
This has been covered many times already, so search Stack Overflow for more discussion and examples.
To localize, specify:
FormatStyle to determine how long or abbreviated should the string be.
Locale to determine:
The human language for translation of name of day, name of month, and such.
The cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
Example:
Locale l = Locale.CANADA_FRENCH ; // Or Locale.US, Locale.JAPAN, etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.LONG )
.withLocale( l );
String output = later.format( f );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Use the SimpleDateFormat class.
Check this http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
Related
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.DateFormat;
import groovy.time.TimeCategory
def startDate = 'Monday, May 11 2015'
def today = new Date().format( 'EEEE, MMM dd yyyy' )
def today1 = quantityService.normalizeAndFormat(today, DatumType.DATE,
Formatters.DATE_IN_WORDS)
def diff = today1.minus(startDate);
The startDate is a string extracted from the database. And is formatted exactly like today1 is formatted above to produce 'Monday, May 11 2015'. I am unable to perform the subtract operation to obtain the value of the variable diff. Can you please guide me on how can I obtain the value of diff in the same format like startDate? Currently, the operation doesn't work probably because startDate is a string and today1 is a date object.
tl;dr
Use modern java.time classes, not the terrible legacy classes. Never use Date or DateFormat or SimpleDateFormat.
Example code in Java syntax:
Period
.between(
LocalDate.parse(
"Monday, May 11 2015" ,
DateTimeFormatter.ofPattern( "EEEE, MMM d uuuu" , Locale.US )
) ,
LocalDate.now( ZoneId.of( "America/Los_Angeles" ) )
)
.toString() ;
P3Y8M18D
Avoid legacy date-time classes
You are using terrible date-time classes that were obsoleted years ago by the java.time classes, with the adoption of JSR 310.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the code becomes ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
DateTimeFormatter
Define a formatting pattern to match your input. (Java syntax)
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEEE, MMM d uuuu" , Locale.US ) ;
String input = "Monday, May 11 2015" ;
LocalDate ld = LocalDate.parse( input , f ) ;
ld.toString(): 2015-05-11
Elapsed time
To calculate elapsed time as years-months-days, use Period. For days (24-hour chunks of time, not calendar days), hours, and seconds, use Duration.
Period p = Period.between( ld , today ) ;
p.toString(): P3Y8M18D
That string in standard ISO 8601 formats means “three years, eight months, and eighteen days”.
See the above code run live at IdeOne.com.
There is no localization feature in java.time to represent a Period or Duration with words. Instead, you can generate your own string.
String output = p.getYears() + " years, " + p.getMonths() + " months, " + p.getDays() + " days" ; // Obviously, you could get fancier by checking for zero or singular values and then adjust the text.
ISO 8601
Avoid exchanging date-time values using localized formats such as that seen in your input. Instead, when exchanging date-time values as text, always use the standard ISO 8601 formats. They were wisely designed to avoid ambiguity. They are easy to parse by machine, and easy to read by humans across cultures.
The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to specify any formatting pattern.
For a date-only value, the standard format is YYYY-MM-DD such as 2019-01-23.
LocalDate ld = LocalDate.parse( "2019-01-23" ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I am trying to parse the String to date. String having date format as
"dd-MMM-yyyy Z" and String having value "12-DEC-2018 ET". Its giving the error
java.text.ParseException: Unparseable date: "12-DEC-2018 ET".
The same code is working for String having value "12-DEC-2018 IST".
below is the code snippet:
public static void main(String[] args) throws ParseException {
String dateInputIST ="12-DEC-2018 IST";
String dateInputET ="12-DEC-2018 ET";
SimpleDateFormat sdfmt1 = new SimpleDateFormat("dd-MMM-yyyy Z");
SimpleDateFormat sdfmt2= new SimpleDateFormat("dd/MM/yyyy");
Date dDate = sdfmt1.parse( dateInputIST );
String strOutput = sdfmt2.format( dDate );
System.out.println(strOutput);
Date etDate = sdfmt1.parse(dateInputET);
strOutput = sdfmt2.format(etDate);
System.out.println(strOutput);
}
Could someone please help. I needed to parse the time in any timezone.
Thanks,
Navin
Change
String dateInputET ="12-DEC-2018 ET";
to
String dateInputET ="12-DEC-2018 EDT";
'ET' is not a recognized time zone.
Pseudo-zones
ET, EST, and IST are not actually time zones. Those 2-4 letter pseudo-zones are not standardized and are not even unique! For example, IST can mean India Standard Time, Ireland Standard Time, Iceland Standard Time, and more.
Real time zone names take the format of Continent/Region such as Africa/Tunis.
Date & zone, separately
Date with time zone has no real meaning.
Handle the date as a LocalDate object.
String input = "12-DEC-2018"
DayeTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" , Locale.US ) ;
LocalDate ld = LocalDate.parse( input , f ) ;
Handle your desired time zone separately, as a ZoneId object.
ZoneId zNewYork = ZoneId.of( "America/New_York" ) ;
To combine, determine the first moment of the day.
ZonedDateTime zdtNewYork = ld.atStartOfDay( z ) ;
Generate text representing that moment in standard ISO 8601 format extended to append the name of the time zone in square brackets.
To see that same moment in UTC, extract a Instant.
Instant instant = zdtNewYork.toInstant() ;
Adjust into another zone.
ZonedDateTime zdtKolkata = instant.atZone( ZoneId.of( "Asia/Kolkata" ) ) ;
To focus on the date only, get a LocalDate for the day of that same moment when viewed through the lens of the wall-clock time used in India.
LocalDate ldKolkata = zdtKolkata.toLocalDate() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
java.time
DateTimeFormatter dateZoneFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("dd-MMM-uuuu v")
.toFormatter(Locale.ENGLISH);
String dateInputIST ="12-DEC-2018 IST";
String dateInputET ="12-DEC-2018 ET";
TemporalAccessor parsed = dateZoneFormatter.parse(dateInputIST);
System.out.println("Date: " + LocalDate.from(parsed) + " Time zone: " + ZoneId.from(parsed));
parsed = dateZoneFormatter.parse(dateInputET);
System.out.println("Date: " + LocalDate.from(parsed) + " Time zone: " + ZoneId.from(parsed));
On my computer the output from this snippet was:
Date: 2018-12-12 Time zone: Atlantic/Reykjavik
Date: 2018-12-12 Time zone: America/New_York
Format pattern letter v is for the generic time-zone name, that is, the name that is the same all year regardless of summer time (DST), for example Eastern Time or short ET.
If you want to control the interpretation of ambiguous time zone abbreviations (of which there are a lot), you may use the two-arg appendGenericZoneText(TextStyle, Set<ZoneId>) where the second argument contains the preferred zones. Still better if there is a way for you to avoid relying on time zone abbreviations altogether since, as I said, they are very often ambiguous.
I am not sure what sense a date with a time zone makes, though.
As an additional point, always specify locale for your formatters so they will also work if the default locale is changed or one day your program runs in a JVM with a different default locale.
Avoid SimpleDateFormat and Date
I don’t think SimpleDateFormat will be able to parse your string. It’s just the same since that class is already long outdated and is renowned for being troublesome, so you should never want to use it anyway.
I stored a Date in sqlite db using INTEGER this:
System.currentTimeMillis()
And now i'm getting it back into a LONG and after to string with this:
myTextView.setText(convertDate(date_in_millis.toString(),"dd/MM/yyyy hh:mm:ss");
using this function
public static String convertDate(String dateInMilliseconds, String dateFormat) {
return DateFormat.format(dateFormat, Long.parseLong(dateInMilliseconds)).toString();
}
I'm in Italy.
Well, first of all i'm losing somewhere hours and minutes.
Second i'm not able to set 24h (with HH instead of hh)
I need to use API level 15 then i cannot use API 24 Libraries and i'm unable to use most answers i found.
tl;dr
Instant.ofEpochMilli( 1_486_373_827_327L )
.atZone( ZoneId.of( "Europe/Rome" ) )
.format(
DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss" )
.withLocale( Locale.ITALY )
)
06/02/2017 10:37:07
Avoid legacy date-time classes
The Question and other Answer are outdated. The troublesome old date-time classes such as java.util.Date, java.util.Calendar, and java.text.SimpleTextFormat are now legacy, supplanted by the java.time classes.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
Adding the library to your Android project is well worth the effort. The legacy date-time classes are a mess; avoiding them will save you much grief.
Using java.time
Convert your integer number that represents a number of milliseconds since the epoch reference date of 1970-01-01-T00:00:00Z to a Instant rather than a Date or Calendar. Call Instant.ofEpochMilli.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.ofEpochMilli( … );
Call toString to generate a String representing the date-time value.
instant.toString(): 2017-02-06T00:07:27.879Z
To see that same moment through the lens of a region’s wall-clock time, apply a time zone to get a ZonedDateTime.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Europe/Rome" );
ZonedDateTime zdt = instant.atZone( z );
zdt.toString():
You can get the JVM’s current default time zone. If critical, you should ask the user to confirm. Beware that, like Locale, the current default can be changed at any moment, even during runtime, by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault();
To generate strings in other formats, you can let java.time automatically localize. To localize, specify:
FormatStyle to determine how long or abbreviated should the string be.
Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
You can ask for the JVM’s current default Locale. If critical, you should confirm with the user.
Locale locale = Locale.getDefault();
Note that locale has nothing to do with time zone, completely orthogonal issues, separate and distinct. Time zone determines the wall-clock time. Locale only applies to generating a string for presentation to the user. You could present a date-time in a Pacific/Auckland time zone with a Finnish locale, or present a date-time in the Europe/Rome with a Thai locale. The title of this Question used the word “Locale” but apparently meant “time zone”.
Example code. In this particular example with this particular formatting pattern, we do not technically need to specify a Locale. But better to make a habit of always specifying a Locale. If you forget to specify, you implicitly rely on the JVM’s current default Locale which can change at any moment during runtime.
Locale l = Locale.ITALY ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT ).withLocale( l ) ;
String output = zdt.format( f );
Or you can specify a formatting pattern.
DateTimeFormatter fCustom = DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss" ).withLocale( l ) ;
String output2 = zdt.format( fCustom );
See example code run live at IdeOne.com.
millis: 1486373827327
instant.toString(): 2017-02-06T09:37:07.327Z
zdt.toString(): 2017-02-06T10:37:07.327+01:00[Europe/Rome]
output: 06/02/17 10.37
output2: 06/02/2017 10:37:07
No need to convert number to string
I see no need to convert your count-from-epoch long integer to a string. If you have a long or Long, just pass the long or the Long. Converting to, and then from, a String adds no value.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
Try using the Calendar class:
public static String convertDate(String dateInMilliseconds, String dateFormat) {
DateFormat df = new SimpleDateFormat(dateFormat);
Calendar c = Calendar.getInstance();
c.setTimeInMillis(Long.parseLong(dateInMilliseconds));
c.add(Calendar.HOUR_OF_DAY, 1); //Work-around to get your lost hour
return df.format(c.getTime());
}
And you can use HH to get 24h
i want to get the date after modifying the day of the week using Calender class in java
i want to print 16 7 2015(DD/MM/YYYY);
int monthIndex=6,weekIndex=2,dayIndex=4;
Calendar c = Calendar.getInstance();
c.set(Calendar.MONTH, (monthIndex + 1));
c.set(Calendar.WEEK_OF_MONTH, weekIndex+1 );
c.set(Calendar.DAY_OF_WEEK, dayIndex+1);
int recurMonth = c.get(Calendar.MONTH);
int recWeek=c.get(Calendar.WEEK_OF_MONTH);
int recurDate = c.get(Calendar.DATE);
int recurYear = c.get(Calendar.YEAR);
int dayofMonth=c.get(Calendar.DAY_OF_MONTH);
int dayofWeek=c.get(Calendar.DAY_OF_WEEK);
int dayofweekinmonth=c.get(Calendar.DAY_OF_WEEK_IN_MONTH);
but its showing wrong date
Its pretty clear, I guess.
Calendar today = Calendar.getInstance();
today.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
today.set(Calendar.WEEK_OF_MONTH, 5);
System.out.println(today.get(Calendar.DATE));
The code is self explanatory.
Format date using SimpleDateFormat:
public void printDate(int weekOfMonth, int dayOFWeek) {
Calendar calendar = Calendar.getInstance(Locale.US);
calendar.set(Calendar.WEEK_OF_MONTH, weekOfMonth);
calendar.set(Calendar.DAY_OF_WEEK, dayOFWeek);
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
System.out.println(df.format(calendar.getTime()));
}
tl;dr
To move to the following Monday:
LocalDate.of( 1986 , 2 , 23 ) // Represent a certain date, without time-of-day and without time zone.
.with( TemporalAdjusters.next( DayOfWeek.MONDAY ) ) // Move to the following Monday.
.format( // Generate a string representing this object’s value, using an automatically localizing formatter.
DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.UK )
)
…or, for "third Monday in the same month":
LocalDate.of( 1986 , 2 , 23 ) // Represent a certain date, without time-of-day and without time zone.
.with( TemporalAdjusters.dayOfWeekInMonth( 3 , DayOfWeek.MONDAY ) ) // Move to the third Monday of the same month.
.format( // Generate a string representing this object’s value, using an automatically localizing formatter.
DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.UK )
)
java.time
The modern approach uses the java.time classes that supplanted the troublesome old legacy date-time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
Adjusters
To move to another date, use a TemporalAdjuster implementation found in the TemporalAdjusters class. Specify the desired day-of-week using a DayOfWeek enum object.
LocalDate nextMonday = ld.with( TemporalAdjusters.next( DayOfWeek.MONDAY ) ) ;
If your goal is something like "move to the third Monday of the month", use another TemporalAdjuster implementation.
TemporalAdjuster ta = TemporalAdjusters.dayOfWeekInMonth( 3 , DayOfWeek.MONDAY ) ;
LocalDate thirdMondayOfSameMonth = ld.with( ta ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
How to check whether the given date is earlier than a month ago? What is the fastest algorithm? I have to take into account that different months have different numbers of days.
Updated to Java 8
The class LocalDate class can be used:
LocalDate aDate = LocalDate.parse("2017-01-01");
return aDate.isBefore( LocalDate.now().minusMonths(1));
For previous versions, the Calendar class would work.
Calendar calendar = Calendar.getInstance();
calendar.add( Calendar.MONTH , -1 );
return aDate.compareTo( calendar.getTime() ) < 0;
Sample code:
import static java.lang.System.out;
import java.time.LocalDate;
public class Sample {
public static void main( String [] args ) {
LocalDate aMonthAgo = LocalDate.now().minusMonths(1);
out.println( LocalDate.parse("2009-12-16").isBefore(aMonthAgo));
out.println( LocalDate.now().isBefore(aMonthAgo));
out.println( LocalDate.parse("2017-12-24").isBefore(aMonthAgo));
}
}
Prints
true
false
false
Using Joda Time:
DateTime dt1 = new DateTime(); //Now
DateTime dt2 = new DateTime(2009,9,1,0,0,0,0); //Other date
if (dt1.plusMonths(-1) > dt2) {
//Date is earlier than a month ago
}
tl;dr
LocalDate.now( ZoneId.of( "America/Montreal" )
.minusMonths( 1 )
.isAfter( LocalDate.parse( "2017-01-23" ) )
java.time
The modern approach uses the java.time classes rather than the troublesome legacy classes such as Date & Calendar.
Today
First get the current date. The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
Calculating month-ago
Next, determine the date a month ago.
LocalDate monthAgo = today.minusMonths( 1 ) ;
Here are the rules used by LocalDate::minusMonths, quoted from Java 8 class doc:
This method subtracts the specified amount from the months field in three steps:
Subtract the input months from the month-of-year field
Check if the resulting date would be invalid
Adjust the day-of-month to the last valid day if necessary
For example, 2007-03-31 minus one month would result in the invalid date 2007-02-31. Instead of returning an invalid result, the last valid day of the month, 2007-02-28, is selected instead.
Or, perhaps in your business rules you meant "30 days" instead of a calendar month.
LocalDate thirtyDaysAgo = today.minusDays( 30 ) ;
Input
You are given a date. That should be passed to your code as a LocalDate object.
LocalDate ld = LocalDate.of( 2017 , Month.JANUARY , 23 ) ;
If coming from a String, use the standard ISO 8601 formats. For other formats, search Stack Overflow for DateTimeFormatter class.
LocalDate ld = LocalDate.parse( "2017-01-23" ) ;
Comparison
Now compare. Call the isBefore, isEqual, isAfter methods.
Boolean outdated = ld.isBefore( monthAgo ) ;
Performance
As for the issue of performance raised in the Question: Don't worry about it. This month-ago calculation and comparison is very unlikely to be a bottleneck in your app. Avoid premature optimization.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.