@greatdayhr/capacitor-datetime-setting 2.0.0 → 2.1.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 CHANGED
@@ -14,8 +14,8 @@ Capacitor plugin for comprehensive date/time management on iOS. Cloned from [dat
14
14
  - Network-optimized with caching and offline fallback
15
15
 
16
16
  **Platform Support:**
17
- - ✅ **iOS**: Full implementation (10 methods)
18
- - **Android**: Not implemented (use native Settings API directly)
17
+ - ✅ **iOS**: Full implementation (12 methods)
18
+ - **Android**: 2 methods (`isDateTimeChanged`, `isDateTimeChangedSimple`)
19
19
  - ❌ **Web**: Not supported
20
20
 
21
21
  ## Installation
@@ -27,6 +27,74 @@ npx cap sync ios
27
27
 
28
28
  ## API
29
29
 
30
+ ### Simple Change Detection
31
+
32
+ #### `isDateTimeChanged()`
33
+
34
+ Check if date/time has been manually changed. Returns `true` if auto date/time is disabled (inverse of auto time enabled).
35
+
36
+ This is a simple wrapper from date_change_checker source that provides a quick boolean check.
37
+
38
+ **Returns:** `Promise<{ changed: boolean }>`
39
+
40
+ **Platform Support:**
41
+ - ✅ iOS
42
+ - ✅ Android
43
+
44
+ **Example:**
45
+
46
+ ```typescript
47
+ import { DateTimeSetting } from '@greatdayhr/capacitor-datetime-setting';
48
+
49
+ const result = await DateTimeSetting.isDateTimeChanged();
50
+ if (result.changed) {
51
+ console.log('Auto date/time is disabled - might be manually changed');
52
+ }
53
+ ```
54
+
55
+ ---
56
+
57
+ #### `isDateTimeChangedSimple()`
58
+
59
+ Simple NTP-based check if date/time has been manually changed. Uses basic 30-second threshold comparison without caching.
60
+
61
+ This method matches Flutter plugin behavior exactly and provides a simpler, more predictable alternative to `isDateTimeChanged()`.
62
+
63
+ **Platform behavior:**
64
+ - **iOS**: Compares device time with NTP server (30s threshold)
65
+ - **Android**: Checks Settings.Global.AUTO_TIME
66
+ - Returns `true` if auto time is disabled or network fails (conservative)
67
+
68
+ **Returns:** `Promise<{ changed: boolean }>`
69
+
70
+ **Platform Support:**
71
+ - ✅ iOS
72
+ - ✅ Android
73
+
74
+ **Example:**
75
+
76
+ ```typescript
77
+ import { DateTimeSetting } from '@greatdayhr/capacitor-datetime-setting';
78
+
79
+ const result = await DateTimeSetting.isDateTimeChangedSimple();
80
+ if (result.changed) {
81
+ console.log('Auto date/time is disabled');
82
+ // This result matches Flutter plugin behavior exactly
83
+ }
84
+ ```
85
+
86
+ **When to use:**
87
+ - ✅ When you need consistent behavior with Flutter `date_change_checker`
88
+ - ✅ When you prefer simple, predictable NTP check without caching
89
+ - ✅ When you want conservative detection (fails closed on network errors)
90
+
91
+ **When to use `isDateTimeChanged()` instead:**
92
+ - ✅ When you need faster responses (uses 30s cache)
93
+ - ✅ When you need offline fallback with timezone checks
94
+ - ✅ When you want battery-optimized network monitoring
95
+
96
+ ---
97
+
30
98
  ### Date/Time Change Detection
31
99
 
32
100
  #### `detectDateTimeChange()`
@@ -421,7 +489,20 @@ This plugin is not supported on web. All methods will throw "Not implemented on
421
489
 
422
490
  See [CHANGELOG.md](CHANGELOG.md) for detailed version history.
423
491
 
424
- **Latest version (2.0.0)**:
492
+ **Latest version (2.1.0)**:
493
+ - ✨ Added `isDateTimeChangedSimple()` method for iOS and Android
494
+ - 🎯 Simple NTP-based detection matching Flutter plugin behavior
495
+ - 📱 iOS: 30-second threshold check without caching
496
+ - 📱 Android: Settings.Global.AUTO_TIME check
497
+ - 🔧 Total: 12 methods (iOS), 2 methods (Android)
498
+
499
+ **Previous version (2.0.1)**:
500
+ - ✨ Added `isDateTimeChanged()` method for iOS and Android
501
+ - 🔧 Simple wrapper returning inverse of `isAutoDateTimeEnabled`
502
+ - 📱 Android now has 1 implemented method
503
+ - 🎯 Total: 11 methods (iOS), 1 method (Android)
504
+
505
+ **Previous version (2.0.0)**:
425
506
  - ✨ Cloned all iOS functionality from date_change_checker Flutter plugin
426
507
  - ✨ Added comprehensive date/time change detection methods (4 methods)
427
508
  - ✨ Added automatic user notifications for date/time changes (iOS)
@@ -1,20 +1,75 @@
1
1
  package com.datetimesetting;
2
2
 
3
+ import android.content.Context;
4
+ import android.provider.Settings;
5
+
6
+ import com.getcapacitor.JSObject;
3
7
  import com.getcapacitor.Plugin;
8
+ import com.getcapacitor.PluginCall;
9
+ import com.getcapacitor.PluginMethod;
4
10
  import com.getcapacitor.annotation.CapacitorPlugin;
5
11
 
6
12
  /**
7
13
  * DateTimeSettingPlugin - Android Implementation
8
14
  *
9
- * Note: All date/time detection methods are iOS-only.
10
- * Android does not implement the comprehensive features from date_change_checker
11
- * because the source plugin itself only has basic Settings checks on Android.
12
- *
13
- * For Android auto time detection, use native Settings API directly:
14
- * Settings.Global.getInt(context.getContentResolver(), Settings.Global.AUTO_TIME, 0) == 1
15
+ * Cloned from date_change_checker Flutter plugin.
16
+ * Android implementation provides simple Settings check.
15
17
  */
16
18
  @CapacitorPlugin(name = "DateTimeSetting")
17
19
  public class DateTimeSettingPlugin extends Plugin {
18
- // All methods are iOS-only
19
- // Android implementation intentionally left minimal as per date_change_checker source
20
+
21
+ /**
22
+ * Check if date/time has been manually changed.
23
+ * Returns true if auto date/time is disabled.
24
+ *
25
+ * This is the inverse of isAutoDateTimeEnabled check.
26
+ * Matches date_change_checker Android implementation.
27
+ */
28
+ @PluginMethod
29
+ public void isDateTimeChanged(PluginCall call) {
30
+ try {
31
+ Context context = getContext();
32
+ boolean isAutoEnabled = isAutoDateTimeEnabled(context);
33
+
34
+ JSObject result = new JSObject();
35
+ // Return !isAutoEnabled to indicate if date/time might be changed
36
+ result.put("changed", !isAutoEnabled);
37
+ call.resolve(result);
38
+ } catch (Exception e) {
39
+ call.reject("Failed to detect date/time change", e);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Simple check if date/time has been manually changed.
45
+ * Uses Settings.Global.AUTO_TIME check (same as isDateTimeChanged).
46
+ *
47
+ * This method provides consistent behavior with iOS simple NTP check.
48
+ * Android uses Settings check instead of NTP.
49
+ *
50
+ * @since 2.1.0
51
+ */
52
+ @PluginMethod
53
+ public void isDateTimeChangedSimple(PluginCall call) {
54
+ // Android: Reuse existing simple Settings check
55
+ // This matches Flutter plugin behavior where Android uses Settings
56
+ isDateTimeChanged(call);
57
+ }
58
+
59
+ /**
60
+ * Helper method to check if automatic date/time is enabled.
61
+ * Uses Settings.Global.AUTO_TIME.
62
+ */
63
+ private boolean isAutoDateTimeEnabled(Context context) {
64
+ try {
65
+ int autoTime = Settings.Global.getInt(
66
+ context.getContentResolver(),
67
+ Settings.Global.AUTO_TIME
68
+ );
69
+ return autoTime == 1;
70
+ } catch (Settings.SettingNotFoundException e) {
71
+ // If setting is not found, assume it's disabled
72
+ return false;
73
+ }
74
+ }
20
75
  }
@@ -32,6 +32,52 @@ export interface DateTimeChangeResult {
32
32
  currentDate: number;
33
33
  }
34
34
  export interface DateTimeSettingPlugin {
35
+ /**
36
+ * Check if date/time has been manually changed.
37
+ * Returns true if auto date/time is disabled (inverse of auto time enabled).
38
+ *
39
+ * This is a simple wrapper from date_change_checker source.
40
+ *
41
+ * @returns Promise with boolean indicating if auto time is disabled
42
+ * @since 2.0.1
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const result = await DateTimeSetting.isDateTimeChanged();
47
+ * if (result.changed) {
48
+ * console.log('Auto date/time is disabled - might be manually changed');
49
+ * }
50
+ * ```
51
+ */
52
+ isDateTimeChanged(): Promise<{
53
+ changed: boolean;
54
+ }>;
55
+ /**
56
+ * Simple NTP-based check if date/time has been manually changed.
57
+ * Uses basic 30-second threshold comparison without caching.
58
+ *
59
+ * This method matches Flutter plugin behavior exactly and provides
60
+ * a simpler, more predictable alternative to isDateTimeChanged().
61
+ *
62
+ * Platform behavior:
63
+ * - iOS: Compares device time with NTP server (30s threshold)
64
+ * - Android: Checks Settings.Global.AUTO_TIME
65
+ * - Returns true if auto time is disabled or network fails (conservative)
66
+ *
67
+ * @returns Promise with boolean indicating if auto time is disabled
68
+ * @since 2.1.0
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * const result = await DateTimeSetting.isDateTimeChangedSimple();
73
+ * if (result.changed) {
74
+ * console.log('Auto date/time is disabled');
75
+ * }
76
+ * ```
77
+ */
78
+ isDateTimeChangedSimple(): Promise<{
79
+ changed: boolean;
80
+ }>;
35
81
  /**
36
82
  * Detects if the device's date/time has been manually changed.
37
83
  * Uses network time comparison for accuracy when available.
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC;;OAEG;IACH,UAAU,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,aAAa,CAAC;IAEjE;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,qBAAqB,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IAGlC;;;;;;;;;;;;;;OAcG;IACH,oBAAoB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAEtD;;;;;;;;;;;;;;OAcG;IACH,iCAAiC,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEnE;;;;;;;;;;;;;;OAcG;IACH,oBAAoB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAEtD;;;;;;;;;;;;;OAaG;IACH,8BAA8B,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAIhE;;;;;;;;;;;;OAYG;IACH,YAAY,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE/C;;;;;;;;;;;;;;;;OAgBG;IACH,kBAAkB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAErD;;;;;;;;;;;;;;;OAeG;IACH,kBAAkB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAInF;;;;;;;;;;;;;;OAcG;IACH,kBAAkB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElE;;;;;;;;;;;;;;;;OAgBG;IACH,kBAAkB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAE5D;;;;;;;;;;;OAWG;IACH,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC"}
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC;;OAEG;IACH,UAAU,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,aAAa,CAAC;IAEjE;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,qBAAqB,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IAClC;;;;;;;;;;;;;;;;OAgBG;IACH,iBAAiB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAEnD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,uBAAuB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAIzD;;;;;;;;;;;;;;OAcG;IACH,oBAAoB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAEtD;;;;;;;;;;;;;;OAcG;IACH,iCAAiC,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEnE;;;;;;;;;;;;;;OAcG;IACH,oBAAoB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAEtD;;;;;;;;;;;;;OAaG;IACH,8BAA8B,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAIhE;;;;;;;;;;;;OAYG;IACH,YAAY,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE/C;;;;;;;;;;;;;;;;OAgBG;IACH,kBAAkB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAErD;;;;;;;;;;;;;;;OAeG;IACH,kBAAkB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAInF;;;;;;;;;;;;;;OAcG;IACH,kBAAkB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElE;;;;;;;;;;;;;;;;OAgBG;IACH,kBAAkB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAE5D;;;;;;;;;;;OAWG;IACH,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC"}
package/dist/esm/web.d.ts CHANGED
@@ -1,6 +1,12 @@
1
1
  import { WebPlugin } from '@capacitor/core';
2
2
  import type { DateTimeSettingPlugin, DateTimeChangeResult } from './definitions';
3
3
  export declare class DateTimeSettingWeb extends WebPlugin implements DateTimeSettingPlugin {
4
+ isDateTimeChanged(): Promise<{
5
+ changed: boolean;
6
+ }>;
7
+ isDateTimeChangedSimple(): Promise<{
8
+ changed: boolean;
9
+ }>;
4
10
  detectDateTimeChange(): Promise<{
5
11
  changed: boolean;
6
12
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEjF,qBAAa,kBAAmB,SAAQ,SAAU,YAAW,qBAAqB;IAExE,oBAAoB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAIrD,iCAAiC,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAIlE,oBAAoB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAIrD,8BAA8B,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAK/D,YAAY,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAI9C,kBAAkB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAIpD,kBAAkB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAKlF,kBAAkB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE,kBAAkB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAI3D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CAGvC"}
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEjF,qBAAa,kBAAmB,SAAQ,SAAU,YAAW,qBAAqB;IACxE,iBAAiB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAIlD,uBAAuB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAKxD,oBAAoB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAIrD,iCAAiC,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAIlE,oBAAoB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAIrD,8BAA8B,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAK/D,YAAY,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAI9C,kBAAkB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAIpD,kBAAkB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAKlF,kBAAkB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE,kBAAkB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAI3D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;CAGvC"}
package/dist/esm/web.js CHANGED
@@ -1,5 +1,11 @@
1
1
  import { WebPlugin } from '@capacitor/core';
2
2
  export class DateTimeSettingWeb extends WebPlugin {
3
+ async isDateTimeChanged() {
4
+ throw this.unimplemented('Not implemented on web.');
5
+ }
6
+ async isDateTimeChangedSimple() {
7
+ throw this.unimplemented('Not implemented on web.');
8
+ }
3
9
  // Date/Time Change Detection
4
10
  async detectDateTimeChange() {
5
11
  throw this.unimplemented('Not implemented on web.');
@@ -7,6 +7,12 @@ const DateTimeSetting = core.registerPlugin('DateTimeSetting', {
7
7
  });
8
8
 
9
9
  class DateTimeSettingWeb extends core.WebPlugin {
10
+ async isDateTimeChanged() {
11
+ throw this.unimplemented('Not implemented on web.');
12
+ }
13
+ async isDateTimeChangedSimple() {
14
+ throw this.unimplemented('Not implemented on web.');
15
+ }
10
16
  // Date/Time Change Detection
11
17
  async detectDateTimeChange() {
12
18
  throw this.unimplemented('Not implemented on web.');
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst DateTimeSetting = registerPlugin('DateTimeSetting', {\n web: () => import('./web').then(m => new m.DateTimeSettingWeb()),\n});\nexport * from './definitions';\nexport { DateTimeSetting };\n","import { WebPlugin } from '@capacitor/core';\nexport class DateTimeSettingWeb extends WebPlugin {\n // Date/Time Change Detection\n async detectDateTimeChange() {\n throw this.unimplemented('Not implemented on web.');\n }\n async detectComprehensiveDateTimeChange() {\n throw this.unimplemented('Not implemented on web.');\n }\n async detectDateOnlyChange() {\n throw this.unimplemented('Not implemented on web.');\n }\n async detectAndNotifyDateTimeChanges() {\n throw this.unimplemented('Not implemented on web.');\n }\n // Time Utilities\n async getLocalTime() {\n throw this.unimplemented('Not implemented on web.');\n }\n async getInternetUTCTime() {\n throw this.unimplemented('Not implemented on web.');\n }\n async convertToLocalTime(options) {\n throw this.unimplemented('Not implemented on web.');\n }\n // Timestamp Management\n async setStoredTimestamp(options) {\n throw this.unimplemented('Not implemented on web.');\n }\n async getStoredTimestamp() {\n throw this.unimplemented('Not implemented on web.');\n }\n async resetDetector() {\n throw this.unimplemented('Not implemented on web.');\n }\n}\n"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,eAAe,GAAGA,mBAAc,CAAC,iBAAiB,EAAE;AAC1D,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,kBAAkB,EAAE,CAAC;AACpE,CAAC;;ACFM,MAAM,kBAAkB,SAASC,cAAS,CAAC;AAClD;AACA,IAAI,MAAM,oBAAoB,GAAG;AACjC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,iCAAiC,GAAG;AAC9C,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,oBAAoB,GAAG;AACjC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,8BAA8B,GAAG;AAC3C,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ;AACA,IAAI,MAAM,YAAY,GAAG;AACzB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,kBAAkB,GAAG;AAC/B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,kBAAkB,CAAC,OAAO,EAAE;AACtC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ;AACA,IAAI,MAAM,kBAAkB,CAAC,OAAO,EAAE;AACtC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,kBAAkB,GAAG;AAC/B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,aAAa,GAAG;AAC1B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ;;;;;;;;;"}
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst DateTimeSetting = registerPlugin('DateTimeSetting', {\n web: () => import('./web').then(m => new m.DateTimeSettingWeb()),\n});\nexport * from './definitions';\nexport { DateTimeSetting };\n","import { WebPlugin } from '@capacitor/core';\nexport class DateTimeSettingWeb extends WebPlugin {\n async isDateTimeChanged() {\n throw this.unimplemented('Not implemented on web.');\n }\n async isDateTimeChangedSimple() {\n throw this.unimplemented('Not implemented on web.');\n }\n // Date/Time Change Detection\n async detectDateTimeChange() {\n throw this.unimplemented('Not implemented on web.');\n }\n async detectComprehensiveDateTimeChange() {\n throw this.unimplemented('Not implemented on web.');\n }\n async detectDateOnlyChange() {\n throw this.unimplemented('Not implemented on web.');\n }\n async detectAndNotifyDateTimeChanges() {\n throw this.unimplemented('Not implemented on web.');\n }\n // Time Utilities\n async getLocalTime() {\n throw this.unimplemented('Not implemented on web.');\n }\n async getInternetUTCTime() {\n throw this.unimplemented('Not implemented on web.');\n }\n async convertToLocalTime(options) {\n throw this.unimplemented('Not implemented on web.');\n }\n // Timestamp Management\n async setStoredTimestamp(options) {\n throw this.unimplemented('Not implemented on web.');\n }\n async getStoredTimestamp() {\n throw this.unimplemented('Not implemented on web.');\n }\n async resetDetector() {\n throw this.unimplemented('Not implemented on web.');\n }\n}\n"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,eAAe,GAAGA,mBAAc,CAAC,iBAAiB,EAAE;AAC1D,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,kBAAkB,EAAE,CAAC;AACpE,CAAC;;ACFM,MAAM,kBAAkB,SAASC,cAAS,CAAC;AAClD,IAAI,MAAM,iBAAiB,GAAG;AAC9B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,uBAAuB,GAAG;AACpC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ;AACA,IAAI,MAAM,oBAAoB,GAAG;AACjC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,iCAAiC,GAAG;AAC9C,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,oBAAoB,GAAG;AACjC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,8BAA8B,GAAG;AAC3C,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ;AACA,IAAI,MAAM,YAAY,GAAG;AACzB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,kBAAkB,GAAG;AAC/B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,kBAAkB,CAAC,OAAO,EAAE;AACtC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ;AACA,IAAI,MAAM,kBAAkB,CAAC,OAAO,EAAE;AACtC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,kBAAkB,GAAG;AAC/B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ,IAAI,MAAM,aAAa,GAAG;AAC1B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;AAC3D,IAAI;AACJ;;;;;;;;;"}
package/dist/plugin.js CHANGED
@@ -6,6 +6,12 @@ var capacitorDatetimeSetting = (function (exports, core) {
6
6
  });
7
7
 
8
8
  class DateTimeSettingWeb extends core.WebPlugin {
9
+ async isDateTimeChanged() {
10
+ throw this.unimplemented('Not implemented on web.');
11
+ }
12
+ async isDateTimeChangedSimple() {
13
+ throw this.unimplemented('Not implemented on web.');
14
+ }
9
15
  // Date/Time Change Detection
10
16
  async detectDateTimeChange() {
11
17
  throw this.unimplemented('Not implemented on web.');
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst DateTimeSetting = registerPlugin('DateTimeSetting', {\n web: () => import('./web').then(m => new m.DateTimeSettingWeb()),\n});\nexport * from './definitions';\nexport { DateTimeSetting };\n","import { WebPlugin } from '@capacitor/core';\nexport class DateTimeSettingWeb extends WebPlugin {\n // Date/Time Change Detection\n async detectDateTimeChange() {\n throw this.unimplemented('Not implemented on web.');\n }\n async detectComprehensiveDateTimeChange() {\n throw this.unimplemented('Not implemented on web.');\n }\n async detectDateOnlyChange() {\n throw this.unimplemented('Not implemented on web.');\n }\n async detectAndNotifyDateTimeChanges() {\n throw this.unimplemented('Not implemented on web.');\n }\n // Time Utilities\n async getLocalTime() {\n throw this.unimplemented('Not implemented on web.');\n }\n async getInternetUTCTime() {\n throw this.unimplemented('Not implemented on web.');\n }\n async convertToLocalTime(options) {\n throw this.unimplemented('Not implemented on web.');\n }\n // Timestamp Management\n async setStoredTimestamp(options) {\n throw this.unimplemented('Not implemented on web.');\n }\n async getStoredTimestamp() {\n throw this.unimplemented('Not implemented on web.');\n }\n async resetDetector() {\n throw this.unimplemented('Not implemented on web.');\n }\n}\n"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,eAAe,GAAGA,mBAAc,CAAC,iBAAiB,EAAE;IAC1D,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,kBAAkB,EAAE,CAAC;IACpE,CAAC;;ICFM,MAAM,kBAAkB,SAASC,cAAS,CAAC;IAClD;IACA,IAAI,MAAM,oBAAoB,GAAG;IACjC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,oBAAoB,GAAG;IACjC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,8BAA8B,GAAG;IAC3C,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ;IACA,IAAI,MAAM,YAAY,GAAG;IACzB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,kBAAkB,CAAC,OAAO,EAAE;IACtC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ;IACA,IAAI,MAAM,kBAAkB,CAAC,OAAO,EAAE;IACtC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,aAAa,GAAG;IAC1B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst DateTimeSetting = registerPlugin('DateTimeSetting', {\n web: () => import('./web').then(m => new m.DateTimeSettingWeb()),\n});\nexport * from './definitions';\nexport { DateTimeSetting };\n","import { WebPlugin } from '@capacitor/core';\nexport class DateTimeSettingWeb extends WebPlugin {\n async isDateTimeChanged() {\n throw this.unimplemented('Not implemented on web.');\n }\n async isDateTimeChangedSimple() {\n throw this.unimplemented('Not implemented on web.');\n }\n // Date/Time Change Detection\n async detectDateTimeChange() {\n throw this.unimplemented('Not implemented on web.');\n }\n async detectComprehensiveDateTimeChange() {\n throw this.unimplemented('Not implemented on web.');\n }\n async detectDateOnlyChange() {\n throw this.unimplemented('Not implemented on web.');\n }\n async detectAndNotifyDateTimeChanges() {\n throw this.unimplemented('Not implemented on web.');\n }\n // Time Utilities\n async getLocalTime() {\n throw this.unimplemented('Not implemented on web.');\n }\n async getInternetUTCTime() {\n throw this.unimplemented('Not implemented on web.');\n }\n async convertToLocalTime(options) {\n throw this.unimplemented('Not implemented on web.');\n }\n // Timestamp Management\n async setStoredTimestamp(options) {\n throw this.unimplemented('Not implemented on web.');\n }\n async getStoredTimestamp() {\n throw this.unimplemented('Not implemented on web.');\n }\n async resetDetector() {\n throw this.unimplemented('Not implemented on web.');\n }\n}\n"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,eAAe,GAAGA,mBAAc,CAAC,iBAAiB,EAAE;IAC1D,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,kBAAkB,EAAE,CAAC;IACpE,CAAC;;ICFM,MAAM,kBAAkB,SAASC,cAAS,CAAC;IAClD,IAAI,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,uBAAuB,GAAG;IACpC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ;IACA,IAAI,MAAM,oBAAoB,GAAG;IACjC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,oBAAoB,GAAG;IACjC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,8BAA8B,GAAG;IAC3C,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ;IACA,IAAI,MAAM,YAAY,GAAG;IACzB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,kBAAkB,CAAC,OAAO,EAAE;IACtC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ;IACA,IAAI,MAAM,kBAAkB,CAAC,OAAO,EAAE;IACtC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ,IAAI,MAAM,aAAa,GAAG;IAC1B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC;IAC3D,IAAI;IACJ;;;;;;;;;;;;;;;"}
@@ -391,6 +391,72 @@ class AutoDateTimeDetector {
391
391
  private static var lastStatusCheckTime: Date?
392
392
  private static let statusCacheInterval: TimeInterval = 30.0 // Cache for 30 seconds
393
393
 
394
+ /**
395
+ * Simple NTP-based check if automatic date/time is enabled (matches Flutter plugin behavior)
396
+ *
397
+ * This method provides a simplified detection approach without caching or complex fallback logic.
398
+ * It directly compares device time with NTP server time using a 30-second threshold.
399
+ *
400
+ * Platform behavior:
401
+ * - Fetches device time (UTC)
402
+ * - Fetches NTP time from worldtimeapi.org
403
+ * - Compares time difference
404
+ * - Returns true if difference ≤ 30 seconds (auto time ON)
405
+ * - Returns false if difference > 30 seconds or network fails (auto time OFF)
406
+ *
407
+ * @param completion Callback with detection result
408
+ */
409
+ static func isAutoDateTimeEnabledSimple(completion: @escaping (Bool) -> Void) {
410
+ // Get device time in UTC
411
+ let deviceTimeUtc = Date()
412
+
413
+ // Create URL request to NTP time server
414
+ guard let url = URL(string: "https://worldtimeapi.org/api/timezone/Etc/UTC") else {
415
+ // Conservative approach: return false if URL creation fails
416
+ completion(false)
417
+ return
418
+ }
419
+
420
+ var request = URLRequest(url: url)
421
+ request.timeoutInterval = 5.0 // 5 second timeout
422
+ request.cachePolicy = .reloadIgnoringLocalAndRemoteCacheData
423
+ request.setValue("application/json", forHTTPHeaderField: "Accept")
424
+
425
+ let task = URLSession.shared.dataTask(with: request) { data, response, error in
426
+ // Check for network errors
427
+ if let error = error {
428
+ print("Simple NTP check - Network error: \(error.localizedDescription)")
429
+ // Conservative approach: return false on network failure (matching Flutter)
430
+ completion(false)
431
+ return
432
+ }
433
+
434
+ // Parse response data
435
+ guard let data = data,
436
+ let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
437
+ let unixTimeString = json["unixtime"] as? Double else {
438
+ print("Simple NTP check - Failed to parse server response")
439
+ // Conservative approach: return false on parse failure
440
+ completion(false)
441
+ return
442
+ }
443
+
444
+ // Get NTP time
445
+ let ntpTimeUtc = Date(timeIntervalSince1970: unixTimeString)
446
+
447
+ // Calculate time difference in seconds
448
+ let timeDifferenceSeconds = abs(deviceTimeUtc.timeIntervalSince(ntpTimeUtc))
449
+
450
+ // Simple threshold check: 30 seconds (matching Flutter plugin)
451
+ let isAutoEnabled = timeDifferenceSeconds <= 30.0
452
+
453
+ print("Simple NTP check - Time difference: \(timeDifferenceSeconds)s, Auto enabled: \(isAutoEnabled)")
454
+ completion(isAutoEnabled)
455
+ }
456
+
457
+ task.resume()
458
+ }
459
+
394
460
  /**
395
461
  * Checks if automatic date/time is enabled on iOS device (async version)
396
462
  * Uses caching to provide instant results and avoid network delays
@@ -5,6 +5,9 @@
5
5
  // Define the plugin using the CAP_PLUGIN Macro, and
6
6
  // each method the plugin supports using the CAP_PLUGIN_METHOD macro.
7
7
  CAP_PLUGIN(DateTimeSettingPlugin, "DateTimeSetting",
8
+ // Simple change detection
9
+ CAP_PLUGIN_METHOD(isDateTimeChanged, CAPPluginReturnPromise);
10
+
8
11
  // Date/Time Change Detection
9
12
  CAP_PLUGIN_METHOD(detectDateTimeChange, CAPPluginReturnPromise);
10
13
  CAP_PLUGIN_METHOD(detectComprehensiveDateTimeChange, CAPPluginReturnPromise);
@@ -24,6 +24,49 @@ public class DateTimeSettingPlugin: CAPPlugin {
24
24
  AutoDateTimeDetector.stopNetworkMonitoring()
25
25
  }
26
26
 
27
+ /**
28
+ * Check if date/time has been manually changed (inverse of auto time enabled).
29
+ * This is a simple wrapper that returns !isAutoDateTimeEnabled.
30
+ /**
31
+ * Check if date/time has been manually changed.
32
+ * Returns true if auto date/time is disabled (inverse of auto time enabled).
33
+ *
34
+ * This is a simple wrapper from date_change_checker source.
35
+ *
36
+ * @since 2.0.1
37
+ */
38
+ @objc func isDateTimeChanged(_ call: CAPPluginCall) {
39
+ AutoDateTimeDetector.isAutoDateTimeEnabled { isEnabled in
40
+ DispatchQueue.main.async {
41
+ // Return !isEnabled to indicate if date/time has been changed
42
+ call.resolve([
43
+ "changed": !isEnabled
44
+ ])
45
+ }
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Simple NTP-based check if date/time has been manually changed.
51
+ * Uses basic 30-second threshold comparison without caching.
52
+ *
53
+ * This method matches Flutter plugin behavior exactly:
54
+ * - iOS: Compares device time with NTP server (30s threshold)
55
+ * - Returns true if auto time is disabled or network fails
56
+ *
57
+ * @since 2.1.0
58
+ */
59
+ @objc func isDateTimeChangedSimple(_ call: CAPPluginCall) {
60
+ AutoDateTimeDetector.isAutoDateTimeEnabledSimple { isEnabled in
61
+ DispatchQueue.main.async {
62
+ // Return !isEnabled to indicate if date/time has been changed
63
+ call.resolve([
64
+ "changed": !isEnabled
65
+ ])
66
+ }
67
+ }
68
+ }
69
+
27
70
  // MARK: - Date/Time Change Detection
28
71
 
29
72
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatdayhr/capacitor-datetime-setting",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Capacitor plugin for comprehensive iOS date/time change detection. Cloned from date_change_checker Flutter plugin.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",