I tried:
TimeZone.getDefault();
I tried:
Calendar mCalendar = new GregorianCalendar();
TimeZone mTimeZone = mCalendar.getTimeZone();
I tried:
Calendar c = Calendar.getInstance();
mTimeZone = c.getTimeZone();
No matter what I try... it gives me a default of 0 and GMT. My app just cannot seem to get the time zone (it should read -4 or ET, i.e. eastern USA time zones)
The strange thing is... my clock displays the correct time on my phone.
the "use automatic time zone" is checked in settings of my android device.
So why can't I get the local time in my app? how does the Android clock able to achieve this but not me?
I have checked online and cant seem to find anything. Is there at least a way to sync with the clock app and receive it's time to display on my app as well? Is there ANY way to get the correct time on my app?
System.getMilliseconds() return the time since epoch, which would only function as the current time in areas that use GMT. (As long as what you are using doesn't make it's own conversion)
To get local time in milliseconds since epoch, you can use this function:
// Kotlin
fun getLocalTime(): Long
{
val currentDate = Calendar.getInstance()
return currentDate.timeInMillis + TimeZone.getDefault().getOffset(currentDate.timeInMillis)
}
Which in Java would probably look like this:
// Java
static long getLocalTime()
{
Calendar currentDate = Calendar.getInstance();
return currentDate.getTimeInMillis() + TimeZone.getDefault().getOffset(currentDate.getTimeInMillis());
}
The function takes the time since epoch and adds to it the timezone offset of the phone's local timezone.
Related
I have some doubts about how it works the Calendar library in Android.
I have implemented a listener to get the selected date in the MaterialDatePicker. With the method addOnPositiveButtonClickListener, I get the date selected in milliseconds but I need to transform these milliseconds to a Date object, BUT! whenever I transform this millisecond to a Date object, I am not getting the right value.
For example, if I select 03/24/2021, when I create a new Date object with the correspondent millisecond I get the next Date -> 03/23/2021.
I am trying different solutions I find in different posts but no one works fine for me.
I am trying to use Calendar but is not working properly either.
fun Long.toDate() : Date {
val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
calendar.timeInMillis = this // calendar.time.time = this
return calendar.time
}
and also try it out with different timeZone
fun Long.toDate() : Date {
val calendar = Calendar.getInstance(TimeZone.getDefault())
calendar.timeInMillis = this // calendar.time.time = this
return calendar.time
}
I have also try to save the millisecond on my Calendar instance with calendar.time.time but also is not working for me.
It is so curious because if I set the next values on my device:
Time zone in New Zealand (GMT+13:45) at 10:00 AM,
I select 03/02/2021, so should return the same date.
For this specific example is working fine (I am in Madrid, Spain GMT+01:00) and is returning the date 03/02/2021.
If it was working bad, should returns 02/02/2021, but for this timeZone is working fine.
But, if I change my device values to:
Time zone to Colombia (GMT-05:00) and I set my device time to 10:00 PM.
I select the same date, 03/02/2021, it should return the same date.
In this case, is returning me the day before, 03/01/2021.
Why MaterialDatePicker is working so bad and how can I fix that without doing so badly tricky code?
I saw it can be fixed used SimpleDateformat, but I would like to keep the timeZone and do it a good way, or at least the best way...
Thanks in advance!
I have a TimePickerDialog which lets the user pick a time. The TimePickerDialog has a onTimeSet method that gets called when the user finished picking the time.
I pass the arguments to a second method, setTime(int hour, int minute) which saves the values and displays a formatted time.
Here is a code snippet of the method:
java.text.DateFormat dateFormatter =
java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT, Locale.getDefault());
DateTime dt = new DateTime();
dt = dt.hourOfDay().setCopy(hour);
dt = dt.minuteOfHour().setCopy(minute);
String text = dateFormatter.format(dt.toDate());
The Problem is that (sometimes, not always) the hour value is off by one or maybe even two hours. I think the cause of the problem has something to do with timezones, but I do not know what the exact cause is. I also think that the problem is caused by the Joda DateTime object, since I did not have any issues before I implemented Joda time AND because it also gets saved with one hour off.
Any ideas what happens / how to fix it?
For this answer, I'm using joda-time 2.7 (although it might work with previous versions).
I'm also assuming that your program only cares about hour and minute (I'm not an Android expert, but I saw docs from TimePickerDialog and it seems to be the case).
So, if you're manipulating only hour and minute, you don't need to use DateTime class (actually you shouldn't in this case).
That's because a DateTime object is "aware" of all date fields, including day, month, year and timezone. So, when you create a new DateTime(), it creates a new object with current date and time in your default timezone. And if the current date in default timezone is in summer time (aka daylight saving time), you can have these hour shifts.
(And I believe that Android takes the default timezone from the device's system, so it can vary according to the device running the code - at least that's how it works in computers, so it shouldn't be different for devices).
As you don't need to know day/month/year and timezone, you can use LocalTime class (org.joda.time.LocalTime) which is a class with only hour and minute fields (and seconds, if you want; if you don't care about seconds, they'll be set to zero). And the best part is: this class doesn't care about timezones, so 10:00 AM will always be 10:00 AM.
You also don't need to use java.text.DateFormat, as joda-time has its own formatters. So the code will be like this:
public void setTime(int hour, int minute) {
// shortTime() is equivalent to DateFormat.SHORT
DateTimeFormatter fmt = DateTimeFormat.shortTime().withLocale(Locale.getDefault());
LocalTime time = new LocalTime(hour, minute);
String text = fmt.print(time);
System.out.println(text);
}
Doing some tests (assuming default locale is en_US):
setTime(9, 30); // prints 9:30 AM
setTime(10, 0); // prints 10:00 AM
PS: the output may vary according to your default Locale (which I also believe it comes from the device's system). If you want a fixed format (independent from locales), you can use DateTimeFormat.forPattern("h:mm a"), which also results in the output above (and when you use formatters this way, the default locale doesn't change the output).
What I need is a time difference between specific timezone ("Russia/Moscow") and local time of the user, difference should be in hours.
I run into problem that the Difference of Time Zones is sometimes false calculated. I calculate difference (in hours) between local offset to UTC of android device and remote offset to UTC. For most user it is fine.. but many user are complaining about the problem.. I am not able to reproduce it at my phone or emulators.
The "wrong" displayed time difference is all ways 1 hour less.
In Moscow it is 15:00, in Europe 12:00. But the user see the offset of 2 hours
here is my code.
String tz="Europe/Moscow"
Calendar mCalendar = new GregorianCalendar();
mCalendar.setTimeZone( TimeZone.getTimeZone(tz));
TimeZone mTimeZone = mCalendar.getTimeZone();
int remote = mTimeZone.getRawOffset()/1000/60/60;
Calendar mCalendar2 = new GregorianCalendar();
TimeZone mTimeZone2 = mCalendar2.getTimeZone();
int local = mTimeZone2.getRawOffset()/1000/60/60;
return local - remote;
You are making the common mistake of equating a Time Zone with a Time Zone Offset. They are two different things. Please read the timezone tag wiki.
When you call getRawOffset, that returns the standard offset for that time zone. To get the offset that's in effect at a particular point in time, you can use getOffset, which takes a parameter of the timestamp for the point in time you are talking about.
Consider the following code, which returns the difference that is currently in effect:
long now = System.currentTimeMillis();
String tz = "Europe/Moscow";
TimeZone mTimeZone = TimeZone.getTimeZone(tz);
int remote = mTimeZone.getOffset(now);
TimeZone mTimeZone2 = TimeZone.getDefault();
int local = mTimeZone2.getOffset(now);
double differenceInHours = (local - remote) / 3600000.0;
return differenceInHours;
Note a couple of things:
I did not need a Calendar class.
The offsets are both for the same "now". You will get different results depending on when you run it.
Not all offsets use a whole number of hours, so this function should return double, not int. For example, try Asia/Kolkata, which uses UTC+5:30 the whole year, or Australia/Adelaide, which alternates between UTC+9:30 and UTC+10:30.
Consider also using Joda-Time, which is a much more robust way of working with time in Java.
I know this is very simple question but I am not able to do it.
I have a code that gets current time but this time is not accurate.
booking.CreateDateTime = DateTime.Now.ToUniversalTime();
When I am booking at 12:00 then in database stores 1:00 that means 1 hour difference.
How can I get accurate time?
Use System.currentTimeMillis() to get the current GMT time in mili seconds since epoch.
Then you can use this value to create a new Date or Calendar object and localize it wherever the user is.
I'm not familiar with what you have there, but ToUniversalTime suggests to me that this is adjusting your time to some fixed time zone (probably GMT)
Use a Date to get the time right now, and then a Calendar to do any time zone changes on it that you want.
Example, assuming CreateDateTime is actually a string of what you said it was:
Date date = new Date();
Calendar calendar = new GregorianCalendar();
calendar.setTime(date);
booking.CreateDateTime = calendar.get(Calendar.HOUR_OF_DAY) + ":" + calendar.get(Calendar.MINUTE));
i am currently using the following line to achieve the time: System.currentTimeInMilis.
I have noticed it doesn't consider time zones,or does it not match the android phone it self by the time, while on the emulator it does match.s
so is there another type of way to get the android clock it self? so when the user adjusts he's phones built in clock, it affects it too?
float getTime()
{
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(System.currentTimeMillis());
cal.setTimeZone(TimeZone.getDefault());
return cal.getTimeInMillis();
}
Read the documentation of currentTimeMillis. It has a time zone, which happens to be UTC (which is the default for Unix time stamps).
If you want to convert it to a different time zone you can make use of the Java Calendar and TimeZone classes:
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(System.currentTimeMillis());
cal.setTimeZone(TimeZone.getDefault());
Alternatively you can just create a new GregorianCalendar instance. By default its TimeZone will match the local one (as set on the device) and the time will be set to "now".
There are also other ways for retrieving the current time according the current time zone and locale as string. Take a look at DateUtils.
EDIT Explaining the usage of Calendar
Read the documentation for Calendar.getTimeMillis(). That method returns the Unix time stamp again which happens to have the time zone UTC.
You have to use the Calendar.get() method instead for getting the correct values. See following example for getting the current hour in the correct time zone via your calendar object:
int hour = cal.get(Calendar.HOUR_OF_HAY);
Read the documentation of Calendar. There are plenty of fields like HOUR_OF_DAY which help you getting values like the year, month, minute, seconds etc.