I am working on Calendar project and I am wondering is there any build in function available in class Calendar in android which can change daily basis or weekly basis.
For e.g. I am storing a data in today's date. And I want to repeat that operation on daily basis or weekly basis.
I don't want to use Calendar api.
e.g.
let's say my Calendar instance variable storing date "2014-26-01"
so I want to do something like
final Calendar c = Calendar.getInstance();
for(int i = o ; i <= 30 ; i++){
yy = c.get(Calendar.YEAR);
mm = c.get(Calendar.MONTH);
dd = c.get(Calendar.DAY_OF_MONTH);
Toast.makeText(this,yy+"-"+mm+"-"+dd,Toast.LENGH_SHORT).show();
/** here i want to change the value of `Calendar c` to next day or next week**/
}
You can use the calendar.add() method to increase or decrease the date.
for example:
public void Calendar getTomorrow(){
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE,1);
//return the calendar with the date of tomorrow
return calendar;
}
public void Calendar getYesterday(){
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE,-1);
//return the calendar with the date of yesterday
return calendar;
}
By the way, the Joda-Time libary offers convenient plusDays, plusWeeks, and plusMonths methods for such calculations.
// java.util.Date dateNow = new java.util.Date();
// Convert a java.util.Date to Joda-Time. Simply pass Date to constructor.
// DateTime now = new DateTime( dateNow, DateTimeZone.forID( "Europe/Paris" ) );
DateTime now = new DateTime( DateTimeZone.forID( "Europe/Paris" ) );
DateTime tomorrow = now.plusDays( 1 );
DateTime nextWeek = now.plusWeeks( 1 );
DateTime firstMomentOfNextWeek = now.plusWeeks( 1 ).withTimeAtStartOfDay();
DateTime nextMonth = now.plusMonths( 1 );
// Convert from Joda-Time back to old outmoded bundled Java class, java.util.Date.
java.util.Date dateNow = now.toDate();
Dump to console…
System.out.println( "now: " + now );
System.out.println( "now in UTC/GMT: " + now.toDateTime( DateTimeZone.UTC ) );
System.out.println( "tomorrow: " + tomorrow );
System.out.println( "nextWeek: " + nextWeek );
System.out.println( "firstMomentOfNextWeek: " + firstMomentOfNextWeek );
System.out.println( "nextMonth: " + nextMonth );
System.out.println( "dateNow: " + dateNow ); // Remember, a j.u.Date lies. The `toString` applies default time zone, but actually a Date has no time zone.
When run…
now: 2014-01-27T00:06:41.982+01:00
now in UTC/GMT: 2014-01-26T23:06:41.982Z
tomorrow: 2014-01-28T00:06:41.982+01:00
nextWeek: 2014-02-03T00:06:41.982+01:00
firstMomentOfNextWeek: 2014-02-03T00:00:00.000+01:00
nextMonth: 2014-02-27T00:06:41.982+01:00
dateNow: Sun Jan 26 15:06:41 PST 2014
Related
I want to get day names between two dates with simple Java, without using any third party library.
I want to get names like Saturday, Sunday, Monday between two days inclusive both.
/**
*
* #param startDate
* #param endDate
* #return Start Date and End Date are <b>Inclusive</b>, days returned between these two dates
*/
protected List<String> getWeekDayNames(Date startDate, Date endDate) {
List<String> days = new ArrayList<String>();
Calendar startCal = Calendar.getInstance();
startCal.setTime(startDate);
Calendar endCal = Calendar.getInstance();
endCal.setTime(endDate);
if (startCal.getTimeInMillis() == endCal.getTimeInMillis()) {
days.add(this.formatDayOfWeek(startCal.getTime()));
return Collections.unmodifiableList(days);
}
// swap values
if (startCal.getTimeInMillis() > endCal.getTimeInMillis()) {
startCal.setTime(endDate);
endCal.setTime(startDate);
}
do {
days.add(this.formatDayOfWeek(startCal.getTime()));
startCal.add(Calendar.DAY_OF_MONTH, 1);
} while (startCal.getTimeInMillis() <= endCal.getTimeInMillis());
return Collections.unmodifiableList(days);
}
Usage:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 15);
List<String> list = new Test().getWeekDayNames(new Date(), cal.getTime());
System.out.println(list);
Output:
[SATURDAY, SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY]
Joda-Time
Usually I would suggest the Joda-Time library, a popular replacement for the notoriously troublesome java.util.Date & java.util.Calendar classes bundled with Java. But the Question requires no third-party libraries.
java.time.*
So, instead of Joda-Time, my code example below uses the new java.time.* package bundled with Java 8. These classes are inspired by Joda-Time, but are entirely re-architected. They are defined by JSR 310. For more information, see the new Tutorial from Oracle.
The solution is quite simple. Boils down to this one-line fragment…
DayOfWeek.from( zonedDateTime ).getDisplayName( TextStyle.FULL, Locale.US );
For fun, I tossed in an extra line to show how easy it is to localize. In this case I show the French as well as US English word for day-of-week.
Here is the entire snippet, ready to run if you import java.time.* and java.time.format.*.
ZoneId timeZone = ZoneId.of( "America/New_York" );
ZonedDateTime start = ZonedDateTime.now( timeZone );
ZonedDateTime stop = start.plusDays( 2 );
// Usually spans of time are handled in a "half-open" manner, meaning start is inclusive and stop is exclusive.
// But the Question required both start and stop to be inclusive. So add "1".
long days = java.time.temporal.ChronoUnit.DAYS.between( start, stop ) + 1L;
System.out.println( days + " days from " + start + " to " + stop + " inclusive…");
for ( int i = 0; i < days; i++ ) {
ZonedDateTime zonedDateTime = start.plusDays( i );
String dayOfWeek = DayOfWeek.from( zonedDateTime ).getDisplayName( TextStyle.FULL, java.util.Locale.US );
String dayOfWeek_Français = DayOfWeek.from( zonedDateTime ).getDisplayName( TextStyle.FULL, java.util.Locale.FRENCH );
System.out.println( "zonedDateTime: " + zonedDateTime + " dayOfWeek: " + dayOfWeek + " dayOfWeek_Français: " + dayOfWeek_Français );
}
When run…
3 days from 2014-02-08T06:06:33.335-05:00[America/New_York] to 2014-02-10T06:06:33.335-05:00[America/New_York] inclusive…
zonedDateTime: 2014-02-08T06:06:33.335-05:00[America/New_York] dayOfWeek: Saturday dayOfWeek_Français: samedi
zonedDateTime: 2014-02-09T06:06:33.335-05:00[America/New_York] dayOfWeek: Sunday dayOfWeek_Français: dimanche
zonedDateTime: 2014-02-10T06:06:33.335-05:00[America/New_York] dayOfWeek: Monday dayOfWeek_Français: lundi
I have a Date Object which I need to convert to the logged in user's timezone. The problem is that the timezone is represented in our DB simply as a String value of GMT plus or minus the offset in hours. So for example "GMT" or "GMT-5" for New york time or "GMT+5".
How can I convert my Date Object to the User's time when all I have are String like "GMT-3" or "GMT+5"?
Thanks in advance for any help.
An example should help, but it seems a 1 character ISO 8601 time zone:
String myDate="2001-07-04T12:08:56GMT-3";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'GMT'X");
if (myDate.indexOf("GMT-") >= myDate.length() -1 -4) {
myDate = myDate.replace("-","-0");
}
if (myDate.indexOf("GMT+") >= myDate.length() -1 -4) {
myDate = myDate.replace("+","+0");
}
System.out.println(format.parse(myDate));
it should work.
the yyyy-MM-dd'T'HH:mm:ss'GMT'X is compliant with iso8601 time zone
myDate = myDate.replace("-","-0"); adjusts the date to your format
Offset ≠ Time Zone
As Jon Skeet said in comment, a time zone is more than just an offset from UTC/GMT. Storing the offset hours (and minutes) is a less-than-optimal strategy for handling date-time in your database/storage.
Joda-Time
The java.util.Date & java.util.Calendar classes are notoriously troublesome. Avoid them. Use Joda-Time. Or, in Java 8, use the new java.time.* package, defined by JSR 310, and inspired by Joda-Time but re-architected.
We can create a DateTimeZone to represent the offset, but as noted this does not make a complete time zone logically.
We can pass a java.util.Date object directly to a Joda-Time DateTime constructor. Along with that we pass a DateTimeZone object. To go the other direction of conversion, call toDate on a DateTime object.
java.util.Date date = new java.util.Date(); // Retrieved from elsewhere. Faked here.
String offsetInput = "GMT-5";
int offsetHours = 0, offsetMinutes = 0;
offsetInput = offsetInput.replace( "GMT", "" ); // Delete 'GMT' characters.
String[] parts = offsetInput.split(":"); // About splitting a string: http://stackoverflow.com/q/3481828/642706
// Handle results of split.
if( parts.length == 0 ) {
// Add some error handling here
}
if ( parts.length >= 1 ) {
offsetHours = Integer.parseInt( parts[0] ); // Retrieve text of first number (zero-based index counting).
}
if ( parts.length >= 2 ) {
offsetMinutes = Integer.parseInt( parts[1] ); // Retrieve text of second number (zero-based index counting).
}
if( parts.length >= 3 ) {
// Add some error handling here
}
DateTimeZone partialTimeZoneWithOnlyOffset = DateTimeZone.forOffsetHoursMinutes( offsetHours, offsetMinutes );
DateTime dateTime = new DateTime( date, partialTimeZoneWithOnlyOffset );
Dump to console…
System.out.println( "date: " + date ); // BEWARE: JVM's default time zone applied in the implicit call to "toString" of a Date. Very misleading.
System.out.println( "partialTimeZoneWithOnlyOffset: " + partialTimeZoneWithOnlyOffset );
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTime with alternate formatting: " + DateTimeFormat.forStyle( "FF" ).withLocale( Locale.US ).print( dateTime ) );
When run…
date: Sat Feb 08 22:40:57 PST 2014
partialTimeZoneWithOnlyOffset: -05:00
dateTime: 2014-02-09T01:40:57.810-05:00
dateTime with alternate formatting: Sunday, February 9, 2014 1:40:57 AM -05:00
i am fetching date from Oracle database using rp.getStart_date() with hibernate
now i want to add 15 days to it and display it. but as cal.add() requires first argument as int,it is showing me numberFormatException on second line..how do i do it?
Date dt=rp.getStart_date();
int s1=Integer.parseInt((dt.toString()));
System.out.println(s1);
SimpleDateFormat sdf=new SimpleDateFormat("dd-MM-yyyy");
Calendar cal=Calendar.getInstance();
cal.add(s1, 15);
System.out.println(sdf.format(cal.getTime()));
please help me out..
Thanks in advance..
Try,
Date dt = rp.getStart_date();
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
Calendar cal = Calendar.getInstance();
cal.setTime(dt);
cal.add(Calendar.DATE, 15); // Add 15 days
String output = sdf.format(cal.getTime());
System.out.println("Output :: "+output);
Neglected Time Zone
The answer by Rakesh KR is close but not quite right. Both the question and that answer fail to think about time zone. If you neglect to specify a time zone, you get the JVM's default time zone. By relying on default time zone, you may have unexpected results.
DST Effect
The add method of java.util.Calendar retains the hour-of-day, adjusting for Daylight Saving Time (DST) and possibly other anomalies. So if you use a time zone (like United States west coast) that changes Daylight Saving Time by an hour during your time span, you actually will have one extra/less hour. That is, your result in hours of adding 15 days is ( ( 15 * 24 ) ± 1 ).
If you were expecting ( 15 * 24 ) consistently, you will be surprised (depending default time zone of JVM).
Demonstration
Since the plusDays method on DateTime class in Joda-Time has the same behavior, I'll demonstrate using Joda-Time. You should be avoiding java.util.Date & java.util.Calendar anyways, but in this scenario the behavior is the same as Joda-Time.
First, for your information, the code from the other answer could be done Joda-Time like this, converting to-and-fro between the java.util.Date world and Joda-Time world. But this code has the same time zone issue (affected by DST).
java.util.Date juDate = new java.util.Date();
java.util.Date juDateLater = new DateTime( juDate ).plusDays( 15 ).toDate() ;
Now using pure Joda-Time let's look at how time zone affects the addition of days. We will run this example code twice, first as-is, then swapping time zones by commenting out the first timeZone line and enabling the line after that.
// Time zone "America/Los_Angeles" begins DST on 2014-03-09 02:00, springing ahead to 03:00.
DateTimeZone timeZone = DateTimeZone.forID( "America/Los_Angeles" );
//DateTimeZone timeZone = DateTimeZone.UTC;
DateTime dateTime_OneAM = new DateTime( 2014, 3, 9, 1, 0, 0, timeZone );
DateTime dateTime_OneAM_Plus15 = dateTime_OneAM.plusDays( 15 );
DateTime dateTime_ThreeAM = new DateTime( 2014, 3, 9, 3, 0, 0, timeZone );
DateTime dateTime_ThreeAM_Plus15 = dateTime_ThreeAM.plusDays( 15 );
long millisElapsedOneAM = ( dateTime_OneAM_Plus15.getMillis() - dateTime_OneAM.getMillis() );
long millisElapsedThreeAM = ( dateTime_ThreeAM_Plus15.getMillis() - dateTime_ThreeAM.getMillis() );
long minutes = ( ( millisElapsedThreeAM - millisElapsedOneAM ) / 1000L / 60L );
Dump to console…
System.out.println( "timeZone " + timeZone );
System.out.println( "dateTime_OneAM " + dateTime_OneAM + " ( UTC/GMT: " + dateTime_OneAM.toDateTime( DateTimeZone.UTC ) + " )" );
System.out.println( "dateTime_OneAM_Plus15 " + dateTime_OneAM_Plus15 + " ( UTC/GMT: " + dateTime_OneAM_Plus15.toDateTime( DateTimeZone.UTC ) + " )" );
System.out.println( " " ); // Blank line.
System.out.println( "dateTime_ThreeAM " + dateTime_ThreeAM + " ( UTC/GMT: " + dateTime_ThreeAM.toDateTime( DateTimeZone.UTC ) + " )" );
System.out.println( "dateTime_ThreeAM_Plus15 " + dateTime_ThreeAM_Plus15 + " ( UTC/GMT: " + dateTime_ThreeAM_Plus15.toDateTime( DateTimeZone.UTC ) + " )" );
System.out.println( " " ); // Blank line.
System.out.println( "millisElapsedOneAM " + millisElapsedOneAM );
System.out.println( "millisElapsedThreeAM " + millisElapsedThreeAM );
System.out.println( "minutes " + minutes );
When run using the first time zone, for US west coast…(Note how hour-of-day in UTC changing or not changing)
timeZone America/Los_Angeles
dateTime_OneAM 2014-03-09T01:00:00.000-08:00 ( UTC/GMT: 2014-03-09T09:00:00.000Z )
dateTime_OneAM_Plus15 2014-03-24T01:00:00.000-07:00 ( UTC/GMT: 2014-03-24T08:00:00.000Z )
dateTime_ThreeAM 2014-03-09T03:00:00.000-07:00 ( UTC/GMT: 2014-03-09T10:00:00.000Z )
dateTime_ThreeAM_Plus15 2014-03-24T03:00:00.000-07:00 ( UTC/GMT: 2014-03-24T10:00:00.000Z )
millisElapsedOneAM 1292400000
millisElapsedThreeAM 1296000000
minutes 60
When run using the second time zone, for UTC/GMT…
timeZone UTC
dateTime_OneAM 2014-03-09T01:00:00.000Z ( UTC/GMT: 2014-03-09T01:00:00.000Z )
dateTime_OneAM_Plus15 2014-03-24T01:00:00.000Z ( UTC/GMT: 2014-03-24T01:00:00.000Z )
dateTime_ThreeAM 2014-03-09T03:00:00.000Z ( UTC/GMT: 2014-03-09T03:00:00.000Z )
dateTime_ThreeAM_Plus15 2014-03-24T03:00:00.000Z ( UTC/GMT: 2014-03-24T03:00:00.000Z )
millisElapsedOneAM 1296000000
millisElapsedThreeAM 1296000000
minutes 0
I want to get a DateTime object using a String with this format, yyyyMMddHHmmss+timezone,
As an example:
20131216014500+0000
It looks like I can use the DateTimeFormatter but I don't really know how, then I am using regular expression to create the DateTime objects. For that I am using this:
Pattern.compile("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])\\+([0-9][0-9][0-9][0-9])");
Matcher m = p.matcher(timestamp);
String match = m.group();
int year = Integer.parseInt(m.group(0));
int monthOfYear = Integer.parseInt(m.group(1));
int dayOfMonth = Integer.parseInt(m.group(2));
int hourOfDay = Integer.parseInt(m.group(3));
int minuteOfHour = Integer.parseInt(m.group(4));
int secondOfMinute = Integer.parseInt(m.group(5));
// TimeZone tz = TimeZone.getTimeZone("");
DateTime date = new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute);
Here I have two problems, one is that I don't know how to set the TimeZone.
The second one is that running this I get java.lang.IllegalStateException.
Any help?
Some example code using Joda-Time 2.3.
Unlike java.util.Date, a Joda-Time DateTime knows its own time zone. You can specify the time zone in the formatter definition if you wish (call withZone). Or you can create a new DateTime instance set to a zone, as seen below, by calling toDateTime and passing a DateTimeZone instance.
String string = "20131216014500+0000";
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyyMMddHHmmssZ");
DateTime dateTime = formatter.parseDateTime( string ); // Default time zone.
// Shift time zone to UTC/GMT.
DateTime dateTimeUtc = dateTime.toDateTime( DateTimeZone.UTC );
// Shift time zone to a named time zone.
// Guessing that "Europe/Madrid" is appropriate for Málaga Spain.
DateTime dateTimeMálaga = dateTime.toDateTime( DateTimeZone.forID( "Europe/Madrid" ) );
Dump to console…
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeMálaga: " + dateTimeMálaga );
When run…
dateTime: 2013-12-15T17:45:00.000-08:00
dateTimeUtc: 2013-12-16T01:45:00.000Z
dateTimeMálaga: 2013-12-16T02:45:00.000+01:00
Regex is not the way to go here. There are java libraries that already solved this problem. See SimpleDateFormat
y Year
M Month
d day
H hour
m minute
s second
Z timezone (RFC 822)
This should probably do it:
DateFormat df = new SimpleDateFormat("yyyyMMddHHmmssZ");
Date result = df.parse(yourString);
DateTime dateTime = new DateTime(result); //to get a joda DateTime object
Edit: JodaTime has a similar class.
The pattern syntax is mostly compatible with java.text.SimpleDateFormat
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMddHHmmssZ");
DateTime dt = fmt.parseDateTime(yourString);
See DateTimeFormat and DateTimeFormatter
Want to get first day of the next week (next monday), but call to getTime() changes the Calendar object.
Please tell me the right way to get first day of the next week.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class Main {
public static void main(String[] args) {
{
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
final Calendar cal = new GregorianCalendar( 2013, 5, 6 );
cal.setFirstDayOfWeek( Calendar.MONDAY );
//System.out.println( sdf.format( cal.getTime() ) );
cal.set( Calendar.DAY_OF_WEEK, Calendar.MONDAY );
System.out.println( sdf.format( cal.getTime() ) ); // 2013-06-06
cal.add( Calendar.WEEK_OF_YEAR, 1 );
System.out.println( sdf.format( cal.getTime() ) ); // 2013-06-13
}
{
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
final Calendar cal = new GregorianCalendar( 2013, 5, 6 );
cal.setFirstDayOfWeek( Calendar.MONDAY );
System.out.println( sdf.format( cal.getTime() ) ); // 2013-06-06
cal.set( Calendar.DAY_OF_WEEK, Calendar.MONDAY );
System.out.println( sdf.format( cal.getTime() ) ); // 2013-06-03
cal.add( Calendar.WEEK_OF_YEAR, 1 );
System.out.println( sdf.format( cal.getTime() ) ); // 2013-06-10
}
}
}
This is a nice example...
The Calendar is not easy to handle. You problem is the evaluation of the date.
The date of the Calendar is newly evaluated if you call e.g. getTime() or add().
In the second (correct) example you call getTime() after setting the first day of the week and the calendar is set to 2013-06-06. After that you change the day of the week and set the calendar new (via getTime()). Therefore it is now set to Monday.
In the first example you set the Calendar to the date and set the day of week. This leads to an invalid date (temporarily). 2013-06-06 is a Thursday and you set Monday. Now which one is the correct day of week? The Calendar implementation now chooses Thursday.
This is also well documented in the Javadoc. The section is named Calendar Fields Resolution.