@@ -60,7 +60,7 @@ describe('migrateUserPreferences', () => {
6060 const result = migrateUserPreferences ( legacyData ) ;
6161
6262 expect ( result ) . toEqual ( {
63- isUTC : false ,
63+ timeZone : 'local' ,
6464 timeFormat : '12h' ,
6565 colorMode : 'dark' ,
6666 font : 'IBM Plex Mono' ,
@@ -84,7 +84,7 @@ describe('migrateUserPreferences', () => {
8484 const result = migrateUserPreferences ( legacyData ) ;
8585
8686 expect ( result ) . toEqual ( {
87- isUTC : true ,
87+ timeZone : 'Etc/UTC' ,
8888 timeFormat : '24h' ,
8989 colorMode : 'light' ,
9090 font : 'Inter' ,
@@ -137,7 +137,7 @@ describe('migrateUserPreferences', () => {
137137 const result = migrateUserPreferences ( legacyData ) ;
138138
139139 expect ( result ) . toEqual ( {
140- isUTC : true ,
140+ timeZone : 'Etc/UTC' ,
141141 timeFormat : '24h' ,
142142 colorMode : 'light' ,
143143 font : 'Roboto Mono' ,
@@ -154,7 +154,7 @@ describe('migrateUserPreferences', () => {
154154 const result = migrateUserPreferences ( legacyData ) ;
155155
156156 expect ( result ) . toEqual ( {
157- isUTC : false , // From DEFAULT_PREFERENCES
157+ timeZone : 'local' , // From DEFAULT_PREFERENCES
158158 timeFormat : '12h' , // From DEFAULT_PREFERENCES
159159 colorMode : 'dark' , // Migrated from theme
160160 font : 'IBM Plex Mono' , // From DEFAULT_PREFERENCES
@@ -221,7 +221,7 @@ describe('migrateUserPreferences', () => {
221221 const result = migrateUserPreferences ( partialData ) ;
222222
223223 expect ( result ) . toEqual ( {
224- isUTC : false , // From DEFAULT_PREFERENCES
224+ timeZone : 'local' , // From DEFAULT_PREFERENCES
225225 timeFormat : '12h' , // From DEFAULT_PREFERENCES
226226 colorMode : 'light' , // Migrated from theme
227227 font : 'IBM Plex Mono' , // From DEFAULT_PREFERENCES
@@ -241,7 +241,7 @@ describe('migrateUserPreferences', () => {
241241 const result = migrateUserPreferences ( legacyData ) ;
242242
243243 expect ( result ) . toEqual ( {
244- isUTC : false ,
244+ timeZone : 'local' ,
245245 timeFormat : '12h' ,
246246 colorMode : 'dark' ,
247247 font : 'IBM Plex Mono' ,
@@ -254,7 +254,7 @@ describe('migrateUserPreferences', () => {
254254 describe ( 'Migration idempotency' , ( ) => {
255255 it ( 'should return already migrated data unchanged' , ( ) => {
256256 const migratedData : UserPreferences = {
257- isUTC : false ,
257+ timeZone : 'local' ,
258258 timeFormat : '12h' ,
259259 colorMode : 'dark' ,
260260 font : 'IBM Plex Mono' ,
@@ -269,7 +269,7 @@ describe('migrateUserPreferences', () => {
269269
270270 it ( 'should accept colorMode "system" as valid' , ( ) => {
271271 const dataWithSystem : UserPreferences = {
272- isUTC : false ,
272+ timeZone : 'local' ,
273273 timeFormat : '12h' ,
274274 colorMode : 'system' ,
275275 font : 'IBM Plex Mono' ,
@@ -286,7 +286,7 @@ describe('migrateUserPreferences', () => {
286286 const mixedData = JSON . stringify ( {
287287 theme : 'light' ,
288288 colorMode : 'dark' ,
289- isUTC : false ,
289+ timeZone : 'local' ,
290290 timeFormat : '12h' ,
291291 font : 'IBM Plex Mono' ,
292292 } ) ;
@@ -323,6 +323,53 @@ describe('migrateUserPreferences', () => {
323323 } ) ;
324324 } ) ;
325325
326+ describe ( 'isUTC migration (isUTC → timeZone)' , ( ) => {
327+ it . each ( [
328+ [ true , 'Etc/UTC' ] ,
329+ [ false , 'local' ] ,
330+ ] ) ( 'replaces isUTC=%s with timeZone=%s and saves it' , ( isUTC , timeZone ) => {
331+ const stored = JSON . stringify ( {
332+ isUTC,
333+ timeFormat : '24h' ,
334+ colorMode : 'dark' ,
335+ font : 'Inter' ,
336+ } ) ;
337+
338+ const result = migrateUserPreferences ( stored ) ;
339+
340+ expect ( result ) . toEqual ( {
341+ timeZone,
342+ timeFormat : '24h' ,
343+ colorMode : 'dark' ,
344+ font : 'Inter' ,
345+ } ) ;
346+ expect ( localStorageMock . setItem ) . toHaveBeenCalledWith (
347+ STORAGE_KEY ,
348+ JSON . stringify ( result ) ,
349+ ) ;
350+ } ) ;
351+
352+ it ( 'defaults to local when neither isUTC nor timeZone is stored' , ( ) => {
353+ const result = migrateUserPreferences (
354+ JSON . stringify ( { colorMode : 'dark' , timeFormat : '12h' } ) ,
355+ ) ;
356+ expect ( result ?. timeZone ) . toBe ( 'local' ) ;
357+ } ) ;
358+
359+ it ( 'keeps a stored timeZone over isUTC' , ( ) => {
360+ const result = migrateUserPreferences (
361+ JSON . stringify ( {
362+ isUTC : true ,
363+ timeZone : 'Asia/Tokyo' ,
364+ colorMode : 'dark' ,
365+ timeFormat : '12h' ,
366+ } ) ,
367+ ) ;
368+ expect ( result ?. timeZone ) . toBe ( 'Asia/Tokyo' ) ;
369+ expect ( result ) . not . toHaveProperty ( 'isUTC' ) ;
370+ } ) ;
371+ } ) ;
372+
326373 describe ( 'localStorage error handling' , ( ) => {
327374 it ( 'should handle localStorage.setItem errors gracefully' , ( ) => {
328375 localStorageMock . setItem . mockImplementation ( ( ) => {
@@ -339,7 +386,7 @@ describe('migrateUserPreferences', () => {
339386 // Should not throw, should return migrated data even if save fails
340387 const result = migrateUserPreferences ( legacyData ) ;
341388 expect ( result ) . toEqual ( {
342- isUTC : false ,
389+ timeZone : 'local' ,
343390 timeFormat : '12h' ,
344391 colorMode : 'dark' ,
345392 font : 'IBM Plex Mono' ,
@@ -365,7 +412,7 @@ describe('migrateUserPreferences', () => {
365412 // Should not throw - should return migrated data
366413 const result = migrateUserPreferences ( legacyData ) ;
367414 expect ( result ) . toEqual ( {
368- isUTC : false ,
415+ timeZone : 'local' ,
369416 timeFormat : '12h' ,
370417 colorMode : 'dark' ,
371418 font : 'IBM Plex Mono' ,
0 commit comments