react-native-timezone 3.1.0 β 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -13
- package/android/src/main/java/com/samitha/timezone/TimezoneModule.kt +2 -1
- package/ios/Timezone.mm +36 -3
- package/package.json +13 -78
package/README.md
CHANGED
|
@@ -1,28 +1,91 @@
|
|
|
1
1
|
# React Native Timezone and Region
|
|
2
2
|
|
|
3
|
-
[](https://codeclimate.com/github/samitha9125/react-native-timezone/maintainability)
|
|
4
|
-
|
|
5
3
|
A Simple react native module to get the Timezone and the Region of the Android/iOS devices.
|
|
6
4
|
|
|
7
|
-
#
|
|
5
|
+
# Why Choose This Library?
|
|
6
|
+
|
|
7
|
+
## π Privacy-First
|
|
8
|
+
Unlike other timezone/region libraries, `react-native-timezone` **does NOT require**:
|
|
9
|
+
- β Location permissions (`ACCESS_FINE_LOCATION`, `ACCESS_COARSE_LOCATION`)
|
|
10
|
+
- β `READ_PHONE_STATE` permission (Android)
|
|
11
|
+
- β Additional native dependencies
|
|
12
|
+
|
|
13
|
+
**This is critical for:**
|
|
14
|
+
- Privacy-conscious apps
|
|
15
|
+
- App Store/Play Store approval (permission justifications)
|
|
16
|
+
- GDPR/CCPA compliance
|
|
17
|
+
|
|
18
|
+
## π± Expo Compatible
|
|
19
|
+
Works seamlessly with **Expo Development Builds** (CNG - Continuous Native Generation):
|
|
20
|
+
```bash
|
|
21
|
+
npx expo install react-native-timezone
|
|
22
|
+
npx expo prebuild
|
|
23
|
+
npx expo run:ios
|
|
24
|
+
```
|
|
8
25
|
|
|
9
|
-
|
|
26
|
+
No need for bare React Native workflowβjust prebuild and run.
|
|
10
27
|
|
|
11
|
-
|
|
28
|
+
## β‘ Super Lightweight
|
|
29
|
+
- Zero JavaScript dependencies
|
|
30
|
+
- Native TurboModule (synchronous, no bridge overhead)
|
|
31
|
+
- Minimal footprint (~2KB gzipped)
|
|
32
|
+
|
|
33
|
+
## π Modern Architecture
|
|
34
|
+
Fully compatible with React Native's New Architecture (Fabric + TurboModules).
|
|
35
|
+
|
|
36
|
+
---
|
|
12
37
|
|
|
13
38
|
# Compatibility
|
|
14
39
|
|
|
15
|
-
|
|
40
|
+
| React Native | New Architecture | Tested | Notes |
|
|
41
|
+
|--------------|------------------|--------|-------|
|
|
42
|
+
| 0.71.x | β
Stable | β
| First stable TurboModule support |
|
|
43
|
+
| 0.72.x | β
| β
| |
|
|
44
|
+
| 0.73.x | β
| β
| |
|
|
45
|
+
| 0.74.x | β
Default | β
| New Arch enabled by default |
|
|
46
|
+
| 0.76.x | β
| β
| |
|
|
47
|
+
| 0.83.x | β
| β
| Latest (Feb 2026) |
|
|
48
|
+
|
|
49
|
+
**Breaking Changes in React Native:**
|
|
50
|
+
- **0.71**: New Architecture stabilized (TurboModules + Fabric)
|
|
51
|
+
- **0.74**: New Architecture enabled by default
|
|
52
|
+
- **0.76**: Minimum iOS deployment target raised to iOS 15.1
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
# β οΈ Important: iOS Carrier API Deprecation
|
|
57
|
+
|
|
58
|
+
Apple has deprecated the entire `CTCarrier` class with **no replacement API**:
|
|
59
|
+
|
|
60
|
+
| API | Deprecated Since | Status |
|
|
61
|
+
|-----|-----------------|--------|
|
|
62
|
+
| `subscriberCellularProvider` | iOS 12 | β οΈ Deprecated |
|
|
63
|
+
| `serviceSubscriberCellularProviders` | iOS 16 | β οΈ Deprecated |
|
|
64
|
+
| `CTCarrier` class | iOS 16 | β No replacement |
|
|
16
65
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
66
|
+
**What this means for `getRegionByTelephony()`:**
|
|
67
|
+
- **iOS < 18**: Works, but triggers deprecation warnings (suppressed in this library)
|
|
68
|
+
- **iOS 18+**: Returns `null` due to Apple's privacy restrictions
|
|
69
|
+
|
|
70
|
+
**Recommended Pattern:**
|
|
71
|
+
```javascript
|
|
72
|
+
// Use telephony-based region with locale fallback
|
|
73
|
+
const region = Timezone.getRegionByTelephony() ?? Timezone.getRegionByLocale();
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This is an Apple platform limitation, not a bug in this library.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
# Motivation
|
|
81
|
+
|
|
82
|
+
For a project of mine, I had to acquire the currently selected timezone of the user. Unfortunately, I could not find any react native package or react native in-build function that facilitates this. Thus I created a small library.
|
|
83
|
+
|
|
84
|
+
v3.0.0 and above, you can access the Region details. More details can be found below.
|
|
22
85
|
|
|
23
86
|
# Installation
|
|
24
87
|
|
|
25
|
-
`
|
|
88
|
+
`yarn add react-native-timezone`
|
|
26
89
|
|
|
27
90
|
## iOS
|
|
28
91
|
|
|
@@ -54,5 +117,5 @@ Check out the [example](https://github.com/samitha9125/react-native-timezone/tre
|
|
|
54
117
|
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
55
118
|
| getTimeZone | Android: Returns timezone ID using `java.util.TimeZone.getID()`<br>iOS: Reflects the current system time zone using `localTimeZone` of `NSTimeZone` |
|
|
56
119
|
| isAutoTimeZoneEnabled | Returns a boolean indicating if auto timezone is enabled on the device **(Android Only)** |
|
|
57
|
-
| getRegionByTelephony | Retrieves the region information based on the telephony (SIM card) of the device. Returns `
|
|
120
|
+
| getRegionByTelephony | Retrieves the region information based on the telephony (SIM card) of the device. Returns `null` if the device has no SIM card. |
|
|
58
121
|
| getRegionByLocale | Retrieves the region information based on the device's locale settings |
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package com.samitha.timezone
|
|
2
2
|
|
|
3
3
|
import android.content.ContentResolver
|
|
4
|
+
import android.content.Context
|
|
4
5
|
import android.os.Build
|
|
5
6
|
import android.provider.Settings
|
|
6
7
|
import android.telephony.TelephonyManager
|
|
@@ -54,7 +55,7 @@ class TimezoneModule(reactContext: ReactApplicationContext) :
|
|
|
54
55
|
@ReactMethod(isBlockingSynchronousMethod = true)
|
|
55
56
|
override fun getRegionByTelephony(): String? {
|
|
56
57
|
return try {
|
|
57
|
-
val telephonyService = reactApplicationContext.getSystemService(
|
|
58
|
+
val telephonyService = reactApplicationContext.getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager
|
|
58
59
|
telephonyService?.networkCountryIso
|
|
59
60
|
} catch (e: Exception) {
|
|
60
61
|
null
|
package/ios/Timezone.mm
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
#import "Timezone.h"
|
|
4
4
|
|
|
5
5
|
@implementation Timezone
|
|
6
|
-
RCT_EXPORT_MODULE(
|
|
6
|
+
RCT_EXPORT_MODULE(Timezone);
|
|
7
7
|
/**
|
|
8
8
|
* This is a Synchronous method.
|
|
9
9
|
* Retrieves the current time zone name.
|
|
@@ -17,15 +17,48 @@
|
|
|
17
17
|
/**
|
|
18
18
|
* Synchronous method.
|
|
19
19
|
* Gets the region based on the telephony manager's network country ISO.
|
|
20
|
+
*
|
|
21
|
+
* β οΈ DEPRECATION NOTICE:
|
|
22
|
+
* - subscriberCellularProvider: Deprecated iOS 12+
|
|
23
|
+
* - serviceSubscriberCellularProviders: Deprecated iOS 16+
|
|
24
|
+
* - CTCarrier class: Deprecated iOS 16+ with NO REPLACEMENT
|
|
25
|
+
*
|
|
26
|
+
* Starting iOS 18, these APIs return nil due to privacy restrictions.
|
|
27
|
+
* Apple has intentionally removed carrier info access with no alternative.
|
|
28
|
+
* Consider using getRegionByLocale() as a fallback.
|
|
20
29
|
*/
|
|
21
30
|
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getRegionByTelephony)
|
|
22
31
|
{
|
|
32
|
+
#pragma clang diagnostic push
|
|
33
|
+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
34
|
+
|
|
23
35
|
CTTelephonyNetworkInfo *networkInfo = [[CTTelephonyNetworkInfo alloc] init];
|
|
24
|
-
|
|
25
|
-
|
|
36
|
+
NSString *isoCountryCode = nil;
|
|
37
|
+
|
|
38
|
+
// iOS 12+: Check all cellular providers (multi-SIM support)
|
|
39
|
+
if (@available(iOS 12.0, *)) {
|
|
40
|
+
NSDictionary *carriers = [networkInfo serviceSubscriberCellularProviders];
|
|
41
|
+
|
|
42
|
+
if (carriers && carriers.count > 0) {
|
|
43
|
+
// Get the first available carrier's country code
|
|
44
|
+
CTCarrier *carrier = [carriers.allValues firstObject];
|
|
45
|
+
isoCountryCode = [carrier isoCountryCode];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Fallback for iOS < 12 OR if iOS 12+ returns nothing
|
|
50
|
+
if (isoCountryCode == nil || [isoCountryCode isEqualToString:@""]) {
|
|
51
|
+
CTCarrier *carrier = [networkInfo subscriberCellularProvider];
|
|
52
|
+
isoCountryCode = [carrier isoCountryCode];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
#pragma clang diagnostic pop
|
|
56
|
+
|
|
57
|
+
// iOS 18+: Will likely return nil due to privacy restrictions
|
|
26
58
|
if (isoCountryCode == nil || [isoCountryCode isEqualToString:@""]) {
|
|
27
59
|
return nil;
|
|
28
60
|
}
|
|
61
|
+
|
|
29
62
|
return isoCountryCode;
|
|
30
63
|
}
|
|
31
64
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-timezone",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "A Simple react native module to get Timezone and Region of the Android/iOS devices.",
|
|
5
5
|
"source": "./src/index.tsx",
|
|
6
6
|
"main": "./lib/commonjs/index.js",
|
|
7
7
|
"module": "./lib/module/index.js",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"example": "pnpm --filter react-native-timezone-example",
|
|
10
|
+
"test": "jest",
|
|
11
|
+
"typecheck": "tsc",
|
|
12
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
13
|
+
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
14
|
+
"prepare": "bob build",
|
|
15
|
+
"release": "release-it"
|
|
16
|
+
},
|
|
8
17
|
"exports": {
|
|
9
18
|
".": {
|
|
10
19
|
"import": {
|
|
@@ -22,7 +31,6 @@
|
|
|
22
31
|
"lib",
|
|
23
32
|
"android",
|
|
24
33
|
"ios",
|
|
25
|
-
"cpp",
|
|
26
34
|
"*.podspec",
|
|
27
35
|
"react-native.config.js",
|
|
28
36
|
"!ios/build",
|
|
@@ -36,20 +44,6 @@
|
|
|
36
44
|
"!**/__mocks__",
|
|
37
45
|
"!**/.*"
|
|
38
46
|
],
|
|
39
|
-
"scripts": {
|
|
40
|
-
"example": "yarn workspace react-native-timezone-example",
|
|
41
|
-
"test": "jest",
|
|
42
|
-
"typecheck": "tsc",
|
|
43
|
-
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
44
|
-
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
45
|
-
"prepare": "bob build",
|
|
46
|
-
"release": "release-it"
|
|
47
|
-
},
|
|
48
|
-
"keywords": [
|
|
49
|
-
"react-native",
|
|
50
|
-
"ios",
|
|
51
|
-
"android"
|
|
52
|
-
],
|
|
53
47
|
"repository": {
|
|
54
48
|
"type": "git",
|
|
55
49
|
"url": "git+https://github.com/samitha9125/react-native-timezone.git"
|
|
@@ -89,69 +83,10 @@
|
|
|
89
83
|
"@types/react": "^18.2.44"
|
|
90
84
|
},
|
|
91
85
|
"peerDependencies": {
|
|
92
|
-
"react": "
|
|
93
|
-
"react-native": "
|
|
94
|
-
},
|
|
95
|
-
"workspaces": [
|
|
96
|
-
"example"
|
|
97
|
-
],
|
|
98
|
-
"packageManager": "yarn@3.6.1",
|
|
99
|
-
"jest": {
|
|
100
|
-
"preset": "react-native",
|
|
101
|
-
"modulePathIgnorePatterns": [
|
|
102
|
-
"<rootDir>/example/node_modules",
|
|
103
|
-
"<rootDir>/lib/"
|
|
104
|
-
]
|
|
105
|
-
},
|
|
106
|
-
"commitlint": {
|
|
107
|
-
"extends": [
|
|
108
|
-
"@commitlint/config-conventional"
|
|
109
|
-
]
|
|
110
|
-
},
|
|
111
|
-
"release-it": {
|
|
112
|
-
"git": {
|
|
113
|
-
"commitMessage": "chore: release ${version}",
|
|
114
|
-
"tagName": "v${version}",
|
|
115
|
-
"requireBranch": "main"
|
|
116
|
-
},
|
|
117
|
-
"npm": {
|
|
118
|
-
"publish": true
|
|
119
|
-
},
|
|
120
|
-
"github": {
|
|
121
|
-
"release": true
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
"eslintConfig": {
|
|
125
|
-
"root": true,
|
|
126
|
-
"extends": [
|
|
127
|
-
"@react-native",
|
|
128
|
-
"prettier"
|
|
129
|
-
],
|
|
130
|
-
"rules": {
|
|
131
|
-
"react/react-in-jsx-scope": "off",
|
|
132
|
-
"prettier/prettier": [
|
|
133
|
-
"error",
|
|
134
|
-
{
|
|
135
|
-
"quoteProps": "consistent",
|
|
136
|
-
"singleQuote": true,
|
|
137
|
-
"tabWidth": 2,
|
|
138
|
-
"trailingComma": "es5",
|
|
139
|
-
"useTabs": false
|
|
140
|
-
}
|
|
141
|
-
]
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
"eslintIgnore": [
|
|
145
|
-
"node_modules/",
|
|
146
|
-
"lib/"
|
|
147
|
-
],
|
|
148
|
-
"prettier": {
|
|
149
|
-
"quoteProps": "consistent",
|
|
150
|
-
"singleQuote": true,
|
|
151
|
-
"tabWidth": 2,
|
|
152
|
-
"trailingComma": "es5",
|
|
153
|
-
"useTabs": false
|
|
86
|
+
"react": ">=18.0.0",
|
|
87
|
+
"react-native": ">=0.71.0"
|
|
154
88
|
},
|
|
89
|
+
"packageManager": "pnpm@9.15.4",
|
|
155
90
|
"react-native-builder-bob": {
|
|
156
91
|
"source": "src",
|
|
157
92
|
"output": "lib",
|