Просмотр исходного кода

date / date-plugin improvements

Adam Shaw 7 лет назад
Родитель
Сommit
837ea9a5cf

+ 7 - 6
plugins/luxon/main.ts

@@ -10,8 +10,12 @@ import * as fc from 'fullcalendar'
     })
   },
 
-  toDuration: function(duration: fc.Duration): Duration {
-    return Duration.fromObject(duration)
+  toDuration: function(calendar: fc.Calendar, duration: fc.Duration): Duration {
+    return Duration.fromObject(
+      fc.assignTo({}, duration, {
+        locale: calendar.dateEnv.locale.codes[0]
+      })
+    )
   }
 
 }
@@ -20,10 +24,7 @@ import * as fc from 'fullcalendar'
 class LuxonNamedTimeZone extends fc.NamedTimeZoneImpl {
 
   offsetForArray(a: number[]): number {
-    // use negative to convert the "real" offset to the "inverse" offset,
-    // which is what builtin JS objects return with Date::getTimezoneOffset
-    // TODO: rethink about doing this internally too
-    return -DateTime.fromObject({
+    return DateTime.fromObject({
       zone: this.name,
       year: a[0],
       month: a[1] + 1, // convert 0-based to 1-based

+ 1 - 3
plugins/moment-timezone/main.ts

@@ -6,9 +6,7 @@ import { NamedTimeZoneImpl, registerNamedTimeZoneImpl } from 'fullcalendar'
 class MomentNamedTimeZone extends NamedTimeZoneImpl {
 
   offsetForArray(a: number[]): number {
-    // use negative to convert the "real" offset to the "inverse" offset,
-    // which is what builtin JS objects return with Date::getTimezoneOffset
-    return -(moment as any).tz(a, this.name).utcOffset()
+    return (moment as any).tz(a, this.name).utcOffset()
   }
 
   timestampToArray(ms: number): number[] {

+ 34 - 25
plugins/moment/main.ts

@@ -4,24 +4,16 @@ import * as fc from 'fullcalendar'
 (fc as any).Moment = {
 
   toMoment: function(calendar: fc.Calendar, date: Date): moment.Moment {
-    let timeZone = calendar.dateEnv.timeZone
-    let mom: moment.Moment
-
-    if (timeZone === 'local') {
-      mom = moment(date)
-    } else if (timeZone === 'UTC' || !(moment as any).tz) {
-      mom = moment.utc(date)
-    } else {
-      mom = (moment as any).tz(date, timeZone)
-    }
-
-    mom.locale(calendar.dateEnv.locale.codes[0])
-
-    return mom
+    return convertToMoment(
+      date,
+      calendar.dateEnv.timeZone,
+      null,
+      calendar.dateEnv.locale.codes[0]
+    )
   },
 
   toDuration: function(fcDuration: fc.Duration): moment.Duration {
-    return moment.duration(fcDuration) // i think all props are accepted?
+    return moment.duration(fcDuration) // momment accepts all the props that fc.Duration already has!
   }
 
 }
@@ -29,19 +21,36 @@ import * as fc from 'fullcalendar'
 // TODO: what about range!!??
 
 fc.registerCmdFormatter('moment', function(cmdStr: string, arg: fc.VerboseFormattingArg) {
+  return convertToMoment(
+    arg.date.array,
+    arg.timeZone,
+    arg.date.timeZoneOffset,
+    arg.localeCodes[0]
+  ).format(cmdStr)
+})
+
+
+function convertToMoment(input: any, timeZone: string, timeZoneOffset: number | null, locale: string): moment.Moment {
   let mom: moment.Moment
 
-  if (arg.timeZone === 'local') {
-    mom = moment(arg.date.array)
-  } else if (arg.timeZone === 'UTC' || !(moment as any).tz) {
-    mom = moment.utc(arg.date.array)
+  if (timeZone === 'local') {
+    mom = moment(input)
+
+  } else if (timeZone === 'UTC') {
+    mom = moment.utc(input)
+
+  } else if ((moment as any).tz) {
+    mom = (moment as any).tz(input, timeZone)
+
   } else {
-    mom = (moment as any).tz(arg.date.array, arg.timeZone)
-  }
+    mom = moment.utc(input)
 
-  // what about accepting a forced timezone if .tz isn't present?
+    if (timeZoneOffset != null) {
+      mom.utcOffset(timeZoneOffset)
+    }
+  }
 
-  mom.locale(arg.localeCodes[0])
+  mom.locale(locale)
 
-  return mom.format(cmdStr)
-})
+  return mom
+}

+ 2 - 2
src/datelib/env.ts

@@ -398,7 +398,7 @@ export class DateEnv {
 
   offsetForMarker(m: DateMarker) {
     if (this.timeZone === 'local') {
-      return arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset()
+      return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset() // convert "inverse" offset to "normal" offset
     } else if (this.timeZone === 'UTC') {
       return 0
     } else if (this.namedTimeZoneImpl) {
@@ -419,7 +419,7 @@ export class DateEnv {
       return new Date(m.valueOf() - (forcedTzo || 0))
     } else {
       return new Date(
-        m.valueOf() +
+        m.valueOf() -
         this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60 // convert minutes -> ms
       )
     }

+ 6 - 6
src/datelib/formatting.ts

@@ -11,7 +11,7 @@ export interface ZonedMarker {
   timeZoneOffset: number
 }
 
-export interface ExpandedZoneMarker extends ZonedMarker {
+export interface ExpandedZonedMarker extends ZonedMarker {
   array: number[],
   year: number,
   month: number,
@@ -23,9 +23,9 @@ export interface ExpandedZoneMarker extends ZonedMarker {
 }
 
 export interface VerboseFormattingArg {
-  date: ExpandedZoneMarker
-  start: ExpandedZoneMarker
-  end?: ExpandedZoneMarker
+  date: ExpandedZonedMarker
+  start: ExpandedZonedMarker
+  end?: ExpandedZonedMarker
   timeZone: string
   localeCodes: string[]
 }
@@ -93,7 +93,7 @@ export function formatIsoTimeString(marker: DateMarker) {
 }
 
 export function formatTimeZoneOffset(minutes: number, doIso = false) {
-  let sign = minutes < 0 ? '+' : '-' // whaaa
+  let sign = minutes < 0 ? '-' : '+'
   let abs = Math.abs(minutes)
   let hours = Math.floor(abs / 60)
   let mins = Math.round(abs % 60)
@@ -121,7 +121,7 @@ export function createVerboseFormattingArg(start: ZonedMarker, end: ZonedMarker,
   }
 }
 
-function expandZonedMarker(dateInfo: ZonedMarker, calendarSystem: CalendarSystem): ExpandedZoneMarker {
+function expandZonedMarker(dateInfo: ZonedMarker, calendarSystem: CalendarSystem): ExpandedZonedMarker {
   let a = calendarSystem.markerToArray(dateInfo.marker)
 
   return {

+ 2 - 2
tests/automated/datelib/formatting-api.js

@@ -18,7 +18,7 @@ describe('formatDate', function() {
       timeZoneName: 'short',
       timeZone: 'America/New_York' // but with no timeZoneImpl
     })
-    expect(str).toBe('September 4, 2018, GMT+5')
+    expect(str).toBe('September 4, 2018, GMT-5')
   })
 
 })
@@ -42,7 +42,7 @@ describe('formatRange', function() {
       timeZoneName: 'short',
       timeZone: 'America/New_York' // but with no timeZoneImpl
     })
-    expect(str).toBe('September 4 - October 4, 2018, GMT+5')
+    expect(str).toBe('September 4 - October 4, 2018, GMT-5')
   })
 
 })

+ 15 - 3
tests/automated/datelib/luxon.js

@@ -69,20 +69,32 @@ describe('luxon plugin', function() {
 
   describe('toDuration', function() {
 
-    it('converts correctly', function() {
+    it('converts numeric values correctly', function() {
       let calendar = new FullCalendar.Calendar(document.createElement('div'), {
         defaultTimedEventDuration: '05:00',
         defaultAllDayEventDuration: { days: 3 }
       })
 
       // hacky way to have a duration parsed
-      let timedDuration = toDuration(calendar.defaultTimedEventDuration)
-      let allDayDuration = toDuration(calendar.defaultAllDayEventDuration)
+      let timedDuration = toDuration(calendar, calendar.defaultTimedEventDuration)
+      let allDayDuration = toDuration(calendar, calendar.defaultAllDayEventDuration)
 
       expect(timedDuration.as('hours')).toBe(5)
       expect(allDayDuration.as('days')).toBe(3)
     })
 
+    it('transfers locale correctly', function() {
+      let calendar = new FullCalendar.Calendar(document.createElement('div'), {
+        defaultTimedEventDuration: '05:00',
+        locale: 'es'
+      })
+
+      // hacky way to have a duration parsed
+      let timedDuration = toDuration(calendar, calendar.defaultTimedEventDuration)
+
+      expect(timedDuration.locale).toBe('es')
+    })
+
   })
 
 })

+ 2 - 2
tests/automated/event-data/Event.formatRange.js

@@ -23,7 +23,7 @@ describe('Event::formatRange', function() {
       initCalendar()
       let event = currentCalendar.getEvents()[0]
       let str = event.formatRange(FORMAT_SETTINGS)
-      expect(str).toBe('September 4 to 5, 2018, GMT+5')
+      expect(str).toBe('September 4 to 5, 2018, GMT-5')
     })
   })
 
@@ -38,7 +38,7 @@ describe('Event::formatRange', function() {
       initCalendar()
       let event = currentCalendar.getEvents()[0]
       let str = event.formatRange(FORMAT_SETTINGS)
-      expect(str).toBe('September 4, 2018, GMT+5')
+      expect(str).toBe('September 4, 2018, GMT-5')
     })
   })