Android and server communication: how to ensure time consistency at both ends
During the development of the AChat project, the project requires that the time of the terminal is correct no matter what time zone is set and where the terminal is located, the time fields in the data packets sent to the server must be synchronized with the server. That is to say, the user buys a new mobile phone or tablet without any date and time zone settings, if the App is installed, the time data can be correct.
I designed it like this. There are three variables in app setting: org_tablet_tm, org_server_tm, and server_timezone. When the App is started, that is, the time when the connection server retrieves the current time and the time zone where the server is located are stored in org_server_tm and server_timezone respectively. At the same moment, the time when the terminal is retrieved is stored in org_tablet_tm.
Defines the now () function, which gets the difference between the current device time plus the org_server_tm-org_tablet_tm.
/*** Always take the server as the standard * @ return */public static Date now () {Date w_ret = new Date (); w_ret.setTime (w_ret.getTime () + (org_server_tm-org_tablet_tm )); return w_ret ;}
Well, even if the time on the device terminal is messy at this time, as long as the time zone is the same as the server time zone, you can use the now () function to obtain the current time on the server.
However, the problem arises. the time zone of each user's terminal device is not necessarily the same as that on the server. It is possible that they did not adjust the time or hook up the automatic synchronization time, at this time, we need to use code to synchronize time on the terminal in different time zones with the server.
First look at this DateTimeConvertToServer function, first subtract the time difference between the current time zone and Greenwich Mean from tm, plus the time difference between the time zone where the server is located and Greenwich Mean, you can calculate the time to the server:
/***** Convert the local time to the current time of the server, before submitting data, convert data of the Date type to * @ param tm * @ return */public static Date DateTimeConvertToServer (Date tm) {if (tm = null) return null; tm = new Date (tm. getTime ()-getDiffTimeZoneRawOffsetStd (TimeZone. getDefault (). getID (); // converts it to Greenwich mean time Date d = new Date (tm. getTime () + getDiffTimeZoneRawOffsetStd (server_timezone); return d ;}
Let's look at the getDiffTimeZoneRawOffsetStd function, which is used to calculate the time difference between the specified time zone and the Greenwich Mean Time Zone (millisecond ):
/***** Calculate the time difference between the specified time zone and Greenwich Mean Time * @ param timeZoneId * @ return */public static int getDiffTimeZoneRawOffsetStd (String timeZoneId) {// return TimeZone. getTimeZone (timeZoneId ). getRawOffset (); TimeZone tz = TimeZone. getTimeZone (timeZoneId); return tz. getOffset (GregorianCalendar. getInstance (tz ). getTimeInMillis ());}
In the parameter, I configure an option "whether to convert to terminal time". If this option is used, nothing will be done, because the Android system can automatically convert the time according to the current time zone. If this option is not used, the server time is displayed. You need to use the DateTimeConvertToServer function to convert the time.
To add this question, the current flat time is messy. the time zone is baku asia/baku, and the server is located in the east 8 area. below is the flat panel:
Data stored on the server:
========================================
Let's talk about it before the end. There is a piece of computation functions with Time Zone difference circulating on the network. They use getRawOffset of TimeZone. At that time, I copied and used them. I tried various time zones. At the beginning, they were suitable, however, when it was tested to Asia/Baku, it suddenly became Petrochemical, and it was no problem for Karachi and uar in the East 5 region. The time zones for the entire Journey to the West since Baku were different for an hour !!! GetRawOffset is used to get the 4 hours difference from Greenwich Mean, but it should be 5 hours !! Due to time issues, I did not carefully analyze the reasons. I will try again later when I have time.