so I have this code in Android
DateFormat formatter = new SimpleDateFormat("HH:mm", Locale.getDefault());
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(millisUntilFinished);
textView.setText(formatter.format(calendar.getTime()));
here is how I am passing the values to this method, where the hours and minutes strings are "8" and "30" for example
Calendar c = Calendar.getInstance();
String s = ApplicationPreferences.getWakeUp(ActivityStage1.this);
String[] separated = s.split("\\:");
String hours = separated[0];
String minutes = separated[1];
c.add(Calendar.DAY_OF_MONTH, 1);
c.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hours));
c.set(Calendar.MINUTE, Integer.parseInt(minutes));
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
long timeUntilStageTwo = (c.getTimeInMillis() - System.currentTimeMillis());
startStageTwoTimer(timeUntilStageTwo);
So the value in the long millisUntilFinished is something like 58441666, which is around 16 hours and 20 min, but for some reason the time it shows at the end in the text view is with 3 hours more, I even tried with different locales passed to SimpleDateFormat, and still the same, why is that happening?
Your Calendar c is in your local UTC+3 timezone while the system clock runs at UTC. Hence the difference of 3 hours.
You can use setTimeZone() to set an explicit timezone on your calendar before computing its millisecond value.
If you prefer to do the computations yourself, you can get the user's timezone with TimeZone.getDefault() and then use getOffset(time) to get the millisecond offset at specified UTC time.
Related
I am trying to pass a string of the form 12:00 into milliseconds based on the current date but I seem unable to get a good understanding of how the Calendar and Date class work to achieve this.
Now I have this code:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
Calendar startTime = Calendar.getInstance();
String alarmPref = preferences.getString(PreferenceUtility.getReminderTimes(context), "12:00");
SimpleDateFormat format = new SimpleDateFormat("HH:mm", Locale.getDefault());
Date date = format.parse(alarmPref);
startTime.setTime(date);
This unfortunaltely gives me when logged like this:
Log.d(TAG, "Time to start:" + futureTime);
Log.d(TAG, "Date: " + date);
Gives the following results:
07-25 14:45:21.057 8409-8409/com.google.developer.bugmaster D/PreferenceUtility:Time PreferenceUtility: 21:20
07-25 14:45:21.057 8409-8409/com.google.developer.bugmaster D/QuizJobScheduler: Time to start:126000
Date: Thu Jan 01 12:00:00 GMT+01:00 1970
As seen the required string is 21:20 ( as expected ) but Time to start remains at the value 126000 and hence I keep getting the date to be Date: Thu Jan 01 12:00:00 GMT+01:00 1970, which of course is a reference to the epoch date and time.
How can I get a reference date and time that refers to the time of 21:20 and for the current date the app is running. Forgive me for my ignorance as I have tried so many literature with no success most likely I am unable to understand them.
Use this code:
String time = "21:20";
String[] splittedTime = time.split(":");
Calendar calendar = Calendar.getInstance();
// Set the current date and time
calendar.setTime(new Date());
// Set the desired hour and minute
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(splittedTime[0]));
calendar.set(Calendar.MINUTE, Integer.parseInt(splittedTime[1]));
// Clear seconds and milliseconds
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// the variable date will get today's date and the desired time
Date date = calendar.getTime();
I hope you understand my comments in the code
Java's Date class does not provide the means to set ONLY the time while using the current calendar day. Android's Calendar class does.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 21);
calendar.set(Calendar.MINUTE, 20);
This above example requires you to parse the time without a SimpleDateFormat. Splitting the string in half (using the ':') and integer parsing the two strings would give you the values to put in.
I am using following code to convert timezone (GMT-3) to device local timezone.
int hour=17,minute=0,day=12,month=6,year=2014;
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT-3"));
cal.set(year, (month-1), day,hour,minute);
cal.setTimeZone(TimeZone.getDefault());
Log.d("Time", cal.get(Calendar.DATE)+"/"+cal.get(Calendar.MONTH)+"/"+cal.get(Calendar.YEAR)+" , "+cal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE)+" "+cal.get(Calendar.AM_PM));
My local timezone is GMT+5:30
Expected result is
Time 13/5/2014, 1:30 0
But I am getting the result
12/5/2014 , 13:30 1
Sorry for you, GregorianCalendar is sometimes the hell. Your problem is following:
If you immediately set the timezone after having set the fields for year, month etc. then this mutable calendar class will only shift the timezone retaining the already set fields containing the local time. Those fields for year, month etc. will NOT be recalculated. This behaviour causes a shift on the global timeline represented by cal.getTime(), too.
In order to force the calendar object to recalculate the fields you need to call a getter. Watch out for following code and especially remove the comment marks to see the effect.
int hour = 17, minute = 0, day = 12, month = 6, year = 2014;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
TimeZone tz1 = TimeZone.getTimeZone("GMT-3");
sdf.setTimeZone(tz1);
Calendar cal = new GregorianCalendar(tz1);
cal.set(year, (month - 1), day, hour, minute);
// System.out.println(sdf.format(cal.getTime()));
// System.out.println("Hour=" + cal.get(Calendar.HOUR_OF_DAY));
TimeZone tz2 = TimeZone.getTimeZone("GMT+0530");
sdf.setTimeZone(tz2);
cal.setTimeZone(tz2);
System.out.println(sdf.format(cal.getTime()));
System.out.println("Hour=" + cal.get(Calendar.HOUR_OF_DAY));
Output with comment-disabled lines:
2014-06-12T17:00+0530
Hour=17
Output with enabled lines after having removed the comment marks:
2014-06-12T17:00-0300
Hour=17
2014-06-13T01:30+0530
Hour=1
I hope someone can help. Im trying to set up a timer that times from the start of a game and displays this time. The problem is that the following section of code gives me the wrong time. Its in the wrong format, and is out by an hour.
private long startTime;
private SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SS");
//Constructor:
startTime = System.currentTimeMillis();
public String getTime() {
long gameTime = System.currentTimeMillis() - startTime;
final Date date = new Date(gameTime);
return timeFormat.format(date);
}
It consistently gives me the output of 01:00:03:203. The seconds are correct, but the 1 hour shouldn't be there, and for format is 3 decimal places instead of the two I thought I specified.
Thank you very much!
Your date is epoch + gameTime. I think you're experiencing a daylight saving shift since the current DST in your location today doesn't match the DST at epoch.
Use a Calendar instead of a Date. Start with today and explicitly wipe out the hour, minute, etc. parts:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 3600000 + 60000 + 1000 + 1);
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SS");
System.out.println(timeFormat.format(cal.getTime()));
The output for the above is: 01:01:01.01
http://ideone.com/DyQcl
Substitute the numbers I have above with gameTime and you're done.
Of course, this may not work once your millisecond ticks exceed the day boundary.
I have a Date object. Now I want to add days to that Date object.
So how that can be done? Actually using Calendar object that can be done I know.
But in my case, I haven't used a calendar objects. Instead only used date object.
For Example, suppose I have a date object
Date dtStartDate=o.getStartDate();
int x=28;
Now what I want to do is to add 28 to this date object, means if the dtStartDate is 1 July 2011
then after adding 28, dtStartDate will be 29 July 2011.
Please suggest it to me.
Thanks in advance
You can add Day using below
Calendar c1 = Calendar.getInstance();
c1.add(Calendar.DAY_OF_MONTH, 1);
Here 1 is number of Day you can add.
OR
Date dtStartDate=o.getStartDate();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Calendar c = Calendar.getInstance();
c.setTime(dtStartDate);
c.add(Calendar.DATE, 3); // number of days to add
String dt = sdf.format(c.getTime()); // dt is now the new date
Toast.makeText(this, "" + dt, 5000).show();
May be your problem solved.
You could add the equivilent number of milliseconds to the time retrieved from Date, e.g.:
long millis = dtStartDate.getTime();
millis = millis + x*24*60*60*1000;
Date dtEndDate = new Date();
dtEndDate.setTime(millis);
You can easily do this in two simple ways my friend. First one is:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 1);
and the second one is:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR_OF_DAY, 24);
I think you would like to find this thing. Though there are so many persons are there who choose the first method.
Thanks.
I have read all of the docs and there doesnt seem to be too much to really explains the date functions, or the lack there of.
I am trying implement the AlarmManger which needs the time in milliseconds (ms) for the trigger. To test I took the current time and added 5 seconds and that was good.
// get a Calendar object with current time
Calendar cal = Calendar.getInstance();
// add 5 minutes to the calendar object
cal.add(Calendar.SECOND, 5);
If I have a date and time how would I get the ms for that time.
Like "3/2/2011 08:15:00"
How do I turn that into milliseconds?
Use this method.
example:
method call for 3/2/2011 08:15:00
D2MS( 3, 2, 2011, 8, 15, 0);
method
public long D2MS(int month, int day, int year, int hour, int minute, int seconds) {
Calendar c = Calendar.getInstance();
c.set(year, month, day, hour, minute, seconds);
return c.getTimeInMillis();
}
When using AlarmManager you have two choices in setting an alarm - the first is time in ms since device reboot (don't understand that option) or, if you want an 'absolute' time, then you need to provide a UTC time in ms.
I think this should work - I've done something similar in the past...
public long getUtcTimeInMillis(String datetime) {
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date date = sdf.parse(datetime);
// getInstance() provides TZ info which can be used to adjust to UTC
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// Get timezone offset then use it to adjust the return value
int offset = cal.getTimeZone().getOffset(cal.getTimeInMillis());
return cal.getTimeInMillis() + offset;
}
Personally I'd recommend trying to use a non-localised format such as yyyy-MM-dd HH:mm:ss for any date/time string you use if you want to cater for users globally.
The ISO 8601 international standard is yyyy-MM-dd HH:mm:ss.SSSZ but I don't normally go that far.