How to handle time zone difference between server

2020-07-03 06:18发布

Suppose that my server located in USA and I live in Russia. We know that they have different time zones.

My application getting text(String) from server. And this text data has Date column in database to keep record date.

When I get data, I also get date knowledge. So I can group them by time. First ones at the top and last ones at the bottom. Whatever...

I wrote a function to show date value more human-readable such as "13 hours", "9 minutes". Server sends me the date in server's (USA) time zone.

When I calculate time on application with Russia time zone (because it's current time zone on application), it calculates wrong. So, it's not stuff what anybody wants.

What should I do to achieve the correct calculation?

Annotation: This application will be used by different countries' citizens. So I can't make the calculation static.

5条回答
欢心
2楼-- · 2020-07-03 06:48

There isn't really such as thing as "Russia time zone" or "USA time zone". Both of those countries have several different time zones. See the Wikipedia articles on Time in Russia and Time in the USA.

You should always write server code such that it is not dependent on the time zone that the server is running in. Usually this is done by storing all time as UTC. Since the client is an Android device, just convert to and from local time on the client, sending just UTC to/from the server.

If you're working in Java, you should probably use Joda Time for your conversions. It is much cleaner and easier to use than the Calendar class.

Update

As Basil pointed out in comments, the Joda-Time project is now in maintenance mode. The team advises migration to the java.time classes defined by JSR 310. For earlier Android, see the ThreeTen-Backport and ThreeTenABP projects. See How to use….

查看更多
ら.Afraid
3楼-- · 2020-07-03 06:49

The Calendar class can convert times between timezones, so long as you know what timezone the server and the client use. To avoid problems in the future if you ever move the server, its best to define what the time in the database should be. I prefer to use UTC for this as its standard, but you can use any timezone you wish, so long as its defined and in your documentation so you'll know in the future.

Here's a question that shows how to do it: Date and time conversion to some other Timezone in java

查看更多
▲ chillily
4楼-- · 2020-07-03 07:01

tl;dr

Time zone is irrelevant for elapsed hours-minutes-seconds.

Duration.between(
    Instant.parse( "2017-12-14T01:34:56.123456789Z" ) ;
    Instant.now() 
)

java.time

The modern approach uses the industry-leading java.time classes. These supplant the troublesome old legacy date-time classes such as Date and Calendar.

Servers should generally be set to a time zone of UTC. And you should never depend on any such setting. Instead, your code should specify the desired/expected time zone.

Your business logic, data storage, and data exchange should all be in UTC as a general rule. When serializing to text, use the standard ISO 8601 formats only.

Apply other time zones when necessary, as when expected by a user in the user interface. So generally you should think of time zones other than UTC as a localization issue.

Instant

The Instant class represents a moment, a point on the timeline in UTC with a resolution of nanoseconds. Getting the current moment is unaffected by time zone settings.

Instant instant = Instant.now() ;

Serializing to text in standard format by calling toString.

String output = instant.toString() ;

You can exchange an Instant with your database.

myPreparedStatement.setObject( … , instant ) ;

…and…

Instant instant = myPreparedStatement.getObject( … , Instant.class ) ;

ZonedDateTime

Apply a ZoneId to get a ZonedDateTime.

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

To generate strings in non-standard formats, use the DateTimeFormatter class. Search Stack Overflow for many examples and discussions.

Duration

To get the number of hours, minutes, seconds elapsed, use the Duration class. Note that you do not need time zones for elapsed time; UTC (Instant) gives the same result.

Duration d = Duration.between( then , Instant.now() ) ;

For earlier Android, see the ThreeTen-Backport and ThreeTenABP projects. See How to use….


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

查看更多
Animai°情兽
5楼-- · 2020-07-03 07:01

If you're working in Java prior to Java 8, you should probably use Joda Time for your conversions. Take a look at this question: Date and time conversion to some other Timezone in java

If you're working in Java 8 and newer (or if you plan to start the upgrade process in your company), Java 8 includes a proper Date/Time library and the creators of Joda recommend switching to using that. Take a look at this question: Joda Time - Convert UTC DateTime to Date - Using a Version 1.2.1.1 of Joda

查看更多
欢心
6楼-- · 2020-07-03 07:10

i don't know how this can be achieved in a programmatic way but i know it can be done :) ... maybe you should try a strategy where you save all your records according to GMT time then on your client side make a formula where it checks the time zone of the client then if it was a negative time zone substitute that amount from the current time record and if it was a positive time zone add that amount to the time record this way it will show to the client according to there time zone ..... ( excuse my grammar :) wish it could )

查看更多
登录 后发表回答