I tried to get the last timestamp in the current month of the year on Android so i found
getActualMaximum of "calendar" instance useful but when i tried to figure out what is the last timestamp of August at 2016 i got wrong number of days 30 instead of 31
public static long getLastTimeStampOfCurrentMonth(int month, int year) {
Calendar cal = Calendar.getInstance();
cal.set(year,month, cal.getActualMaximum(Calendar.DAY_OF_MONTH), 23,59,59);
return cal.getTimeInMillis();
}
I found a solution for this case when i took the minimum of the following month minus one:
public static long getLastTimeStampOfCurrentMonth(int month, int year) {
Calendar cal = Calendar.getInstance();
cal.set(year,month, cal.getActualMinimum(Calendar.DAY_OF_MONTH)-1, 23,59,59);
return cal.getTimeInMillis();
}
I am curious about what caused the problem... (May i found a bug)
import java.util.Calendar;
public class test_cal {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(getLastTimeStampOfCurrentMonth(Calendar.AUGUST,2016));
}
public static long getLastTimeStampOfCurrentMonth(int month, int year) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);//leap year 29 Feb;)
cal.set(Calendar.MONTH, month);
cal.set(year,month, cal.getActualMaximum(Calendar.DAY_OF_MONTH), cal.getActualMaximum(Calendar.HOUR_OF_DAY),cal.getActualMaximum(Calendar.MINUTE),cal.getActualMaximum(Calendar.SECOND));
cal.set(Calendar.MILLISECOND,cal.getActualMaximum(Calendar.MILLISECOND));
return cal.getTimeInMillis();
}
}
Use this method for get timestamp of last day of Current month...
private long getLastTimeStampOfCurrentMonth() {
Calendar calendar = Calendar.getInstance();
// passing month-1 because 0-->jan, 1-->feb... 11-->dec
calendar.set(Calendar.getInstance().get((Calendar.YEAR)), Calendar.getInstance().get(Calendar.DAY_OF_MONTH), 1);
calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
Date date = calendar.getTime();
return date.getTime();
}
Related
I have a Date object in Java stored as Java's Date type.
I also have a Gregorian Calendar created date. The gregorian calendar date has no parameters and therefore is an instance of today's date (and time?).
With the java date, I want to be able to get the year, month, day, hour, minute, and seconds from the java date type and compare the the gregoriancalendar date.
I saw that at the moment the Java date is stored as a long and the only methods available seem to just write the long as a formatted date string. Is there a way to access Year, month, day, etc?
I saw that the getYear(), getMonth(), etc. methods for Date class have been deprecated. I was wondering what's the best practice to use the Java Date instance I have with the GregorianCalendar date.
My end goal is to do a date calculation so that I can check that the Java date is within so many hours, minutes etc of today's date and time.
I'm still a newbie to Java and am getting a bit puzzled by this.
Use something like:
Date date; // your date
// Choose time zone in which you want to interpret your Date
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"));
cal.setTime(date);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
// etc.
Beware, months start at 0, not 1.
Edit: Since Java 8 it's better to use java.time.LocalDate rather than java.util.Calendar. See this answer for how to do it.
With Java 8 and later, you can convert the Date object to a LocalDate object and then easily get the year, month and day.
Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
int year = localDate.getYear();
int month = localDate.getMonthValue();
int day = localDate.getDayOfMonth();
Note that getMonthValue() returns an int value from 1 to 12.
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE");
System.out.println("DAY "+simpleDateFormat.format(date).toUpperCase());
simpleDateFormat = new SimpleDateFormat("MMMM");
System.out.println("MONTH "+simpleDateFormat.format(date).toUpperCase());
simpleDateFormat = new SimpleDateFormat("YYYY");
System.out.println("YEAR "+simpleDateFormat.format(date).toUpperCase());
EDIT: The output for date = Fri Jun 15 09:20:21 CEST 2018 is:
DAY FRIDAY
MONTH JUNE
YEAR 2018
You could do something like this, it will explain how the Date class works.
String currentDateString = "02/27/2012 17:00:00";
SimpleDateFormat sd = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date currentDate = sd.parse(currentDateString);
String yourDateString = "02/28/2012 15:00:00";
SimpleDateFormat yourDateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date yourDate = yourDateFormat.parse(yourDateString);
if (yourDate.after(currentDate)) {
System.out.println("After");
} else if(yourDate.equals(currentDate)) {
System.out.println("Same");
} else {
System.out.println("Before");
}
private boolean isSameDay(Date date1, Date date2) {
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(date1);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(date2);
boolean sameYear = calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
boolean sameMonth = calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH);
boolean sameDay = calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH);
return (sameDay && sameMonth && sameYear);
}
It might be easier
Date date1 = new Date("31-May-2017");
OR
java.sql.Date date1 = new java.sql.Date((new Date()).getTime());
SimpleDateFormat formatNowDay = new SimpleDateFormat("dd");
SimpleDateFormat formatNowMonth = new SimpleDateFormat("MM");
SimpleDateFormat formatNowYear = new SimpleDateFormat("YYYY");
String currentDay = formatNowDay.format(date1);
String currentMonth = formatNowMonth.format(date1);
String currentYear = formatNowYear.format(date1);
Date queueDate = new SimpleDateFormat("yyyy-MM-dd").parse(inputDtStr);
Calendar queueDateCal = Calendar.getInstance();
queueDateCal.setTime(queueDate);
if(queueDateCal.get(Calendar.DAY_OF_YEAR)==Calendar.getInstance().get(Calendar.DAY_OF_YEAR))
{
"same day of the year!";
}
#Test
public void testDate() throws ParseException {
long start = System.currentTimeMillis();
long round = 100000l;
for (int i = 0; i < round; i++) {
StringUtil.getYearMonthDay(new Date());
}
long mid = System.currentTimeMillis();
for (int i = 0; i < round; i++) {
StringUtil.getYearMonthDay2(new Date());
}
long end = System.currentTimeMillis();
System.out.println(mid - start);
System.out.println(end - mid);
}
public static Date getYearMonthDay(Date date) throws ParseException {
SimpleDateFormat f = new SimpleDateFormat("yyyyyMMdd");
String dateStr = f.format(date);
return f.parse(dateStr);
}
public static Date getYearMonthDay2(Date date) throws ParseException {
Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.HOUR_OF_DAY, 0);
return c.getTime();
}
public static int compare(Date today, Date future, Date past) {
Date today1 = StringUtil.getYearMonthDay2(today);
Date future1 = StringUtil.getYearMonthDay2(future);
Date past1 = StringUtil.getYearMonthDay2(past);
return today.compare // or today.after or today.before
}
getYearMonthDay2(the calendar solution) is ten times faster. Now you have yyyy MM dd 00 00 00, and then compare using date.compare
import java.util.GregorianCalendar;
public class CalendarMain {
public static void main(String[] args) {
GregorianCalendar calendar = new GregorianCalendar();
int month = calendar.get(GregorianCalendar.MONTH)+1;
int year = calendar.get(GregorianCalendar.YEAR);
int weekday = calendar.get(GregorianCalendar.DAY_OF_WEEK);
int dayOfMonth = calendar.get(GregorianCalendar.DAY_OF_MONTH);
System.out.println(month+"/"+dayOfMonth+"/"+year);
calendar.add(GregorianCalendar.DAY_OF_MONTH, 10);
System.out.println(GregorianCalendar.DAY_OF_MONTH);
}
}
I am trying to add 10 days to the current date but am getting a weird problem. It does not seem to be adding correctly.
Output:
9/18/2014
5
// Get a calendar which is set to a specified date.
Calendar calendar = new GregorianCalendar(2014, Calendar.JANUARY, 1);
// Get the current date representation of the calendar.
Date startDate = calendar.getTime();
// Increment the calendar's date by 1 day.
calendar.add(Calendar.DAY_OF_MONTH, 1);
// Get the current date representation of the calendar.
Date endDate = calendar.getTime();
System.out.println(startDate);
System.out.println(endDate);
I think the last row is wrong, try this:
System.out.println(calendar.get(GregorianCalendar.DAY_OF_MONTH));
Use
System.out.println(calendar.get(GregorianCalendar.DAY_OF_MONTH));
instead of
System.out.println(GregorianCalendar.DAY_OF_MONTH);
Output :
9/18/2014
28
What you were doing in your code is printing the integer code of GregorianCalendar.DAY_OF_MONTH final variable, Which will remain 5, no matter what you have added in calendar. You were needed to use calendar.get(...) function to get the date of month of this calendar.
I ma trying to write a Junit for the following code;
/**
* Check if a date is greater than 24 hours
* #param dateToCheck the date to check
* #return true if it is greater than otherwise false
*/
public static boolean dateGreaterThan24Hours(Date dateToCheck){
if(dateToCheck == null){
throw new IllegalArgumentException("The date passed to check for greater than 24 hours is null");
}
long millisIn24Hours = 1000 * 60 * 60 * 24;
Date hours24ago = new Date(new Date().getTime() - millisIn24Hours);
if (dateToCheck.before(hours24ago)) {
//24 hrs have passed
return true;
}
return false;
}
However I am struggling to do so because the method only accepts a date to check against. Meaning y current attempt at a test method is clearly going to fail;
#Test
public void checkLessThan24HoursShouldReturnTrue(){
//Calendar represents the 7th of July 2014 at 17.30pm
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2014);
cal.set(Calendar.MONTH, 07);
cal.set(Calendar.DAY_OF_MONTH, 7);
cal.set(Calendar.HOUR_OF_DAY,17);
cal.set(Calendar.MINUTE,30);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
Date july7 = cal.getTime();
//Calendar represents the 6th of July 2014 at 18.30pm
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2014);
cal.set(Calendar.MONTH, 07);
cal.set(Calendar.DAY_OF_MONTH, 6);
cal.set(Calendar.HOUR_OF_DAY,18);
cal.set(Calendar.MINUTE,30);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
Date july6 = cal.getTime();
}
Can anyone suggest how i can refactor the original method to make it easier to test?
Thanks
You don't have to change the original method. The easiest tests to write would be:
#Test
public void checkMoreThan24HoursShouldReturnTrue() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR_OF_DAY, -25);
assertTrue(YourClass.dateGreaterThan24Hours(cal.getTime()));
}
#Test
public void checkLessThan24HoursShouldReturnFalse() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR_OF_DAY, -23);
assertFalse(YourClass.dateGreaterThan24Hours(cal.getTime()));
}
Also I would recommend some refactorings as suggested by #DaveNewton in the comments, and a test that verifies your custom exception for null argument.
If you can use the new Java 8 Classes (or JodaTime) you can write much cleaner code.
Plus, depending on why you want 24 hrs ago, there might be bugs regarding Daylight savings time since you only do 24 hrs as milliseconds which might not be a full day ago on certain days.
Here is the equivalent code using the new Java 8 time library. I renamed the method to be more intent revealing and added a Clock optional parameter that allows you to set the time for tests:
public static boolean checkDateMorethan24HrsOld(Date dateToCheck){
return checkDateMorethan24HrsOld(dateToCheck, Clock.systemDefaultZone());
}
public static boolean checkDateMorethan24HrsOld(Date dateToCheck, Clock clock){
if(dateToCheck == null){
//maybe throw NullPointerInstead?
throw new IllegalArgumentException("The date is null");
}
Objects.requireNonNull(clock);
//use clock.instant().minus(Period.ofDays(1)) to support DST
Instant time24HrsAgo =clock.instant().minus(Duration.ofHours(24));
return dateToCheck.toInstant().compareTo(time24HrsAgo) <0;
}
Then your test:
#Test
public void checkLessThan24HoursShouldReturnTrue(){
Instant clocktime = Instant.parse("2014-07-07T17:30:00Z");
Clock clock =Clock.fixed(clocktime, ZoneId.systemDefault());
assertTrue(checkDateMorethan24HrsOld(Date.from(clocktime.minus(Duration.ofDays(2))), clock));
assertFalse("exactly 24 hrs ago",
checkDateMorethan24HrsOld(Date.from(clocktime.minus(Duration.ofDays(1))), clock));
assertFalse(checkDateMorethan24HrsOld(Date.from(clocktime.minus(Duration.ofHours(1))), clock));
}
Of course this code is even simplier if the method takes an Instant instead of Date.
If you could refactor you code to be test friendly:
static final long millisIn24Hours = 1000 * 60 * 60 * 24;
public static boolean dateGreaterThan24Hours(Date dateToCheck){
return dateGreaterThan(dateToCheck,
Calendar.getInstance().getTime(), - millisIn24Hours);
}
public static boolean dateGreaterThan(Date date, Date than, long msDiff) {
if(date == null){
throw new IllegalArgumentException("date is null");
}
if(than == null){
throw new IllegalArgumentException("than is null");
}
return date.before(new Date(than.getTime() + msDiff));
}
You could have somethign like this:
public void testDateGreaterTrue() {
Date now = new Date();
assertFalse(dateGreaterThan(now,
new Date(now.getTime()-millisIn24Hours), millisIn24Hours));
}
public void testDateGreaterFalse() {
Date now = new Date();
assertFalse(dateGreaterThan(now,
new Date(now.getTime()-millisIn24Hours-1), millisIn24Hours));
}
Instead of:
public void testDateGreaterThan24HoursTrue() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) - 25);
assertTrue(dateGreaterThan24Hours(cal.getTime()));
}
public void testDateGreaterThan24HoursFalse() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) - 23);
cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 59);
cal.set(Calendar.SECOND, cal.get(Calendar.SECOND) + 59);
assertFalse(dateGreaterThan24Hours(cal.getTime()));
}
What is most convenient and shortest way to get start and end dates of the previous week?
Example: today is 2011-10-12 (input data),but I want to get 2011-10-03 (Monday's date of previous week) and 2011-10-09 (Sunday's date of previous week).
Here's another JodaTime solution. Since you seem to want Dates only (not timestamps), I'd use the DateMidnight class:
final DateTime input = new DateTime();
System.out.println(input);
final DateMidnight startOfLastWeek =
new DateMidnight(input.minusWeeks(1).withDayOfWeek(DateTimeConstants.MONDAY));
System.out.println(startOfLastWeek);
final DateMidnight endOfLastWeek = startOfLastWeek.plusDays(6);
System.out.println(endOfLastWeek);
Output:
2011-10-12T18:13:50.865+02:00
2011-10-03T00:00:00.000+02:00
2011-10-10T00:00:00.000+02:00
public static Calendar firstDayOfLastWeek(Calendar c) {
c = (Calendar) c.clone();
// last week
c.add(Calendar.WEEK_OF_YEAR, -1);
// first day
c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
return c;
}
public static Calendar lastDayOfLastWeek(Calendar c) {
c = (Calendar) c.clone();
// first day of this week
c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
// last day of previous week
c.add(Calendar.DAY_OF_MONTH, -1);
return c;
}
I would go for #maerics answer if third party library is not involved. I have to replace roll() method with add() method as roll will leave the higher field unchanged. e.g., 22nd August will be obtained from 1st August being rolled -7 days. Note the month remain unchanged.
The source code goes as below.
public static Calendar[] getLastWeekBounds(Calendar c) {
int cdow = c.get(Calendar.DAY_OF_WEEK);
Calendar lastMon = (Calendar) c.clone();
lastMon.add(Calendar.DATE, -7 - (cdow - Calendar.MONDAY));
Calendar lastSun = (Calendar) lastMon.clone();
lastSun.add(Calendar.DATE, 6);
return new Calendar[] { lastMon, lastSun };
}
You can use the Calendar.roll(int,int) method with arguments Calendar.DATE and an offset for the current day of week:
public static Calendar[] getLastWeekBounds(Calendar c) {
int cdow = c.get(Calendar.DAY_OF_WEEK);
Calendar lastMon = (Calendar) c.clone();
lastMon.roll(Calendar.DATE, -7 - (cdow - Calendar.MONDAY));
Calendar lastSun = (Calendar) lastMon.clone();
lastSun.roll(Calendar.DATE, 6);
return new Calendar[] { lastMon, lastSun };
}
This function returns an array of two Calendars, the first being last week's Monday and last week's Sunday.
Wow, the Java date APIs are terrible.
Calendar today = Calendar.getInstance();
Calendar lastWeekSunday = (today.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) ? today.roll(-7): today.roll(Calendar.DAY_OF_YEAR, Calendar.SUNDAY - today.get(Calendar.DAY_OF_WEEK));
Calendar lastWeekMonday = lastWeekSunday.roll( Calendar.DAY_OF_YEAR, -6 );
Using Joda:
DateTime input;
DateTime startOfLastWeek = input.minusWeeks(1).minusDays(input.getDayOfWeek()-1);
DateTime endOfLastWeek = input.minusWeeks(1).plusDays(input.getDayOfWeek()+1);
DateTime endOfLastWeek = startOfLastWeek.plusDays(6);
EDIT:
Joda does not allow a different first day of the week, but strictly sticks to the ISO standard, which states that a week always starts on Monday. However, if you need to make that configurable, you could pass the desired first day of the week as a parameter. See the above link for some other ideas.
public DateTime getFirstDayOfPreviousWeek(DateTime input)
{
return getFirstDayOfPreviousWeek(input, DateTimeConstants.MONDAY);
}
public DateTime getFirstDayOfPreviousWeek(DateTime input, int firstDayOfWeek)
{
return new DateTime(input.minusWeeks(1).withDayOfWeek(firstDayOfWeek));
}
public DateTime getLastDayOfPreviousWeek(DateTime input)
{
return getLastDayOfPreviousWeek(input, DateTimeConstants.MONDAY);
}
public DateTime getLastDayOfPreviousWeek(DateTime input, int firstDayOfWeek)
{
return new DateTime(getFirstDayOfPreviousWeek(input, firstDayOfWeek).plusDays(6));
}
I'm having trouble getting the right format here. I'm trying to get a proper date from my android date picker to shove into a date object.
For example:
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)
public void onTimeSet(TimePicker view, int hourOfDay, int minute)
Those event handlers will give me: 2011, 7, 5 10,30 (if the date was August 5th, 2011 and the time was 10:30) Where do I get Am/Pm in Android?
I'm doing this but its not working right:
Date date = new Date(year,monthOfYear,dayOfMonth,hourOfDay,minute);
I need to accomplish the Android equivalent of this blackberry code. Blackberry date picker graciously provides a date object (rather than raw integers):
public void run() {
DateTimePicker datePicker = DateTimePicker.createInstance();
// Set the max time to 24 hours into the future. This allows for selecting clips
// across time zones, but prevents the user from wandering off into no-mans' land.
Calendar maxDateTime = Calendar.getInstance();
maxDateTime.setTime(new Date(System.currentTimeMillis() + 24*3600*1000));
datePicker.setMaximumDate(maxDateTime);
if (datePicker.doModal())
{
Calendar selectedDate = datePicker.getDateTime();
Date beforeDate = selectedDate.getTime();
ClipStore.getInstance().getClips(camera, beforeDate);
}
}
Use a Calendar :
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, monthOfYear);
cal.set(Calendar.DATE, dayOfMonth);
cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
cal.set(Calendar.MINUTE, minute);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Date date = cal.getTime();
The hour of day goes from 0 to 23.
I believe that hourOfDay uses 24-hour time, so it should be a value between 0 and 23 inclusive. If it's greater >=12, it's PM.
By stock the Java.util will use Military time. aka 10:30 refers to 10:30 AM. 10:30 pm will be shown as 22:30. If you want to convert it to pm try something like this:
public String ampmChanger (String time) {
int hour = (int)time.substring(0,2);
String timeAppendage;
if (hour > 12) { // For 1 PM and on
hour -= 12;
timeAppendage = " PM";
}
else if (hour == 12) timeAppendage = " PM"; // For 12 pm
else timeAppendage = " AM"; // For 0(12AM) to Noon
return String.valueOf(hour)+time.substring(2)+timeAppendage;
}