英文:
Android how to get UTC Timezone offset even of negative timezone
问题
嗨,我正试图将UTC偏移发送到我的服务器。因此,我正在使用以下代码将设备时区转换为UTC偏移
TimeZone tz = TimeZone.getDefault();
Calendar cal = GregorianCalendar.getInstance(tz);
int offsetInMillis = tz.getOffset(cal.getTimeInMillis());
String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000), Math.abs((offsetInMillis / 60000) % 60));
Log.d("UTC_Offset", offset);
现在我知道,因为我使用了Math.abs,它不会给我负值,但我真的不知道如何获取那些处于负值的时区(如GMT-07:00的Tijuana)的偏移量
**注意:**我对UTC中的偏移可能有误解,但这个解决方案是我在Stack Overflow上找到的。如果有任何解决方案,或者如果我在想法上有误,也请告诉我,UTC是否可能为负值
英文:
Hi I am trying to send the UTC offset towards my server. So I am converting the device time zone into utc offset using following code
TimeZone tz = TimeZone.getDefault();
Calendar cal = GregorianCalendar.getInstance(tz);
int offsetInMillis = tz.getOffset(cal.getTimeInMillis());
String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000), Math.abs((offsetInMillis / 60000) % 60));
Log.d("UTC_Offset",offset);
Now i know as I am using the Math.abs it is not giving me the minus values but I am really dumb to know that how could I get the offset of those timezone who are in negative such as Tijuana which is GMT-07:00
Note: I may be wrong about the offset thing in UTC but this solution I found on SO. Please let me know if there is any solution or also correct me if I am wrong in idea and its that UTC could not be in negative
答案1
得分: 2
ZoneId.of("America/Tijuana").getRules().getOffset(Instant.now()).getTotalSeconds()
-25200
org.threeten.bp.ZoneId
.systemDefault()
.getRules()
.getOffset(
Instant.now()
)
.toString()
ZoneId z = ZoneId.systemDefault();
ZoneRules rules = z.getRules();
ZoneOffset offset = rules.getOffset(Instant.now());
String output = offset.toString();
-07:00
ZoneId z = ZoneId.of("America/Tijuana");
ZoneRules rules = z.getRules();
ZoneOffset offset = rules.getOffset(Instant.now());
String output = offset.toString();
System.out.println(output);
-07:00
java.time
The modern approach uses the modern java.time classes. You are using terrible date-time classes that were years ago supplanted by java.time.
Get the [offset-from-UTC][2] of the computer’s [current default][3] [time zone][4].
ZoneId z = ZoneId.systemDefault();
ZoneRules rules = z.getRules();
ZoneOffset offset = rules.getOffset(Instant.now());
Notice that we passed a moment, represented as Instant
object (a moment as seen in UTC). Politicians frequently change the offset used by the zone(s) of their jurisdiction. So the offset of your zone is likely to change over time. So you must specify a moment to ask for the offset that was in effect at that point in time.
Generate text representing that offset, using standard [ISO 8601][5] format.
String output = offset.toString();
-07:00
When receiving such text, you can parse as a ZoneOffset
object.
ZoneOffset offset = ZoneOffset.parse("-07:00");
You asked:
that UTC could not be in negative
A negative offset means a place whose clocks run behind UTC. Generally, this means west (left) of the prime meridian, such as the Americas.
A positive offset means a place whose clocks run ahead of UTC. Generally, this means east (right) of the prime meridian, such as Europe, Africa, Asia.
Well, this is the commonly used meaning of positive & negative offsets, defined in the ISO 8601 standard. Some protocols and industries may use the opposite meaning. Always understand the intention of any data source you may be using.
how could I get the offset of those timezone who are in negative such as Tijuana which is GMT-07:00
ZoneId z = ZoneId.of("America/Tijuana");
ZoneRules rules = z.getRules();
ZoneOffset offset = rules.getOffset(Instant.now());
String output = offset.toString();
System.out.println(output);
-07:00
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
.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes.
Where to obtain the java.time classes?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and Java SE 7
- Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
<details>
<summary>英文:</summary>
# tl;dr
> how could I get the offset of those timezone who are in negative such as Tijuana which is GMT-07:00
ZoneId.of( "America/Tijuana" ).getRules().getOffset( Instant.now() ).getTotalSeconds()
>-25200
- No need to do the math yourself. We have classes for this: [*java.time*](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html).
- For older Java before Java 8, use the [*ThreeTen-Backport*][1] library.
- For older Android, see the [*ThreeTenABP*](https://github.com/JakeWharton/ThreeTenABP) project.
- Avoid `Date`, `Calendar`, `SimpleDateFormat`, and `TimeZone` legacy classes.
Example:
org.threeten.bp.ZoneId
.systemDefault()
.getRules()
.getOffset(
Instant.now()
)
.toString()
To get total seconds of that offset, call `ZoneOffset::getTotalSeconds`.
# *java.time*
The modern approach uses the modern *java.time* classes. You are using terrible date-time classes that were years ago supplanted by *java.time*.
Get the [offset-from-UTC][2] of the computer’s [current default][3] [time zone][4].
ZoneId z = ZoneId.systemDefault() ;
ZoneRules rules = z.getRules() ;
ZoneOffset offset = rules.getOffset( Instant.now() ) ;
Notice that we passed a moment, represented as `Instant` object (a moment as seen in UTC). Politicians frequently change the offset used by the zone(s) of their jurisdiction. So the offset of your zone is likely to change over time. So you must specify a moment to ask for the offset that was in effect at that point in time.
Generate text representing that offset, using standard [ISO 8601][5] format.
String output = offset.toString() ;
>-07:00
When receiving such text, you can parse as a `ZoneOffset` object.
ZoneOffset offset = ZoneOffset.parse( "-07:00" ) ;
You asked:
> that UTC could not be in negative
An negative offset means a place whose clocks run *behind* UTC. Generally, this means west (left) of the prime meridian, such as the Americas.
A positive offset means a place whose clocks run *ahead* of UTC. Generally, this means east (right) of the prime meridian, such as Europe, Africa, Asia.
Well, this is the commonly used meaning of positive & negative offsets, defined in the ISO 8601 standard. Some protocols and industries may use the opposite meaning. Always understand the intention of any data source you may be using.
> how could I get the offset of those timezone who are in negative such as Tijuana which is GMT-07:00
ZoneId z = ZoneId.of( "America/Tijuana" ) ;
ZoneRules rules = z.getRules() ;
ZoneOffset offset = rules.getOffset( Instant.now() ) ;
String output = offset.toString() ;
System.out.println( output ) ;
See this [code run live at IdeOne.com][6].
>-07:00
----------
# About *java.time*
The [*java.time*](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html) framework is built into Java 8 and later. These classes supplant the troublesome old [legacy](https://en.wikipedia.org/wiki/Legacy_system) date-time classes such as [`java.util.Date`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Date.html), [`Calendar`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Calendar.html), & [`SimpleDateFormat`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/text/SimpleDateFormat.html).
To learn more, see the [*Oracle Tutorial*](http://docs.oracle.com/javase/tutorial/datetime/TOC.html). And search Stack Overflow for many examples and explanations. Specification is [JSR 310](https://jcp.org/en/jsr/detail?id=310).
The [*Joda-Time*](http://www.joda.org/joda-time/) project, now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), advises migration to the [java.time](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html) classes.
You may exchange *java.time* objects directly with your database. Use a [JDBC driver](https://en.wikipedia.org/wiki/JDBC_driver) compliant with [JDBC 4.2](http://openjdk.java.net/jeps/170) or later. No need for strings, no need for `java.sql.*` classes.
Where to obtain the java.time classes?
- [**Java SE 8**](https://en.wikipedia.org/wiki/Java_version_history#Java_SE_8), [**Java SE 9**](https://en.wikipedia.org/wiki/Java_version_history#Java_SE_9), [**Java SE 10**](https://en.wikipedia.org/wiki/Java_version_history#Java_SE_10), [**Java SE 11**](https://en.wikipedia.org/wiki/Java_version_history#Java_SE_11), and later - Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- [**Java SE 6**](https://en.wikipedia.org/wiki/Java_version_history#Java_SE_6) and [**Java SE 7**](https://en.wikipedia.org/wiki/Java_version_history#Java_SE_7)
- Most of the *java.time* functionality is back-ported to Java 6 & 7 in [***ThreeTen-Backport***](http://www.threeten.org/threetenbp/).
- [**Android**](https://en.wikipedia.org/wiki/Android_(operating_system))
- Later versions of Android bundle implementations of the *java.time* classes.
- For earlier Android (<26), the [***ThreeTenABP***](https://github.com/JakeWharton/ThreeTenABP) project adapts [***ThreeTen-Backport***](http://www.threeten.org/threetenbp/) (mentioned above). See [*How to use ThreeTenABP…*](http://stackoverflow.com/q/38922754/642706).
[1]: https://www.threeten.org/threetenbp/
[2]: https://en.wikipedia.org/wiki/UTC_offset
[3]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/ZoneId.html#systemDefault()
[4]: https://en.wikipedia.org/wiki/Time_zone
[5]: https://en.wikipedia.org/wiki/ISO_8601
[6]: https://ideone.com/jcnyIt
</details>
# 答案2
**得分**: 1
使用`SimpleDateFormat`来为您格式化:
```java
String offset = new SimpleDateFormat("Z").format(new Date());
offset = offset.substring(0, 3) + ":" + offset.substring(3);
↓↓↓↓↓ 如果以下部分令人困惑,请忽略答案的其余部分 ↓↓↓↓↓
将其应用于Java虚拟机中的所有时区时的结果:
-12:00
-11:00
-10:00
-09:30
-09:00
-08:00
-07:00
-06:00
-05:00
-04:00
-03:00
-02:30
-02:00
-01:00
+00:00
+01:00
+02:00
+03:00
+04:00
+04:30
+05:00
+05:30
+05:45
+06:00
+06:30
+07:00
+08:00
+08:45
+09:00
+09:30
+10:00
+10:30
+11:00
+12:00
+12:45
+13:00
+14:00
用于打印上述结果的Java 8代码:
Instant now = Instant.now();
SimpleDateFormat fmt = new SimpleDateFormat("Z");
ZoneId.getAvailableZoneIds().stream()
.map(z -> ZoneId.of(z).getRules().getOffset(now))
.distinct()
.sorted(Comparator.reverseOrder())
.forEach(z -> {
fmt.setTimeZone(TimeZone.getTimeZone(z));
String offset = fmt.format(Date.from(now));
offset = offset.substring(0, 3) + ":" + offset.substring(3);
System.out.println(offset);
});
英文:
Use SimpleDateFormat
to format it for you:
String offset = new SimpleDateFormat("Z").format(new Date());
offset = offset.substring(0, 3) + ":" + offset.substring(3);
↓↓↓↓↓ IGNORE REST OF ANSWER IF IT IS CONFUSING ↓↓↓↓↓
Results when applying to all TimeZones in the Java VM:
-12:00
-11:00
-10:00
-09:30
-09:00
-08:00
-07:00
-06:00
-05:00
-04:00
-03:00
-02:30
-02:00
-01:00
+00:00
+01:00
+02:00
+03:00
+04:00
+04:30
+05:00
+05:30
+05:45
+06:00
+06:30
+07:00
+08:00
+08:45
+09:00
+09:30
+10:00
+10:30
+11:00
+12:00
+12:45
+13:00
+14:00
Java 8 code to print the above:
Instant now = Instant.now();
SimpleDateFormat fmt = new SimpleDateFormat("Z");
ZoneId.getAvailableZoneIds().stream()
.map(z -> ZoneId.of(z).getRules().getOffset(now))
.distinct()
.sorted(Comparator.reverseOrder())
.forEach(z -> {
fmt.setTimeZone(TimeZone.getTimeZone(z));
String offset = fmt.format(Date.from(now));
offset = offset.substring(0, 3) + ":" + offset.substring(3);
System.out.println(offset);
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论