@@ -79,27 +79,6 @@ const msToSec = (ms) => (ms != null && Number.isFinite(Number(ms))) ? Number(ms)
7979// Calendar formatting helpers
8080// ---------------------------------------------------------------------------
8181
82- /**
83- * Resolve the localised month name (or abbreviation) from CONFIG.
84- * Returns null if the calendar config is not available.
85- *
86- * @param {number } monthIndex – 0-based month index from timeToComponents
87- * @param {"full"|"abbr" } form
88- */
89- function calendarMonthName ( monthIndex , form = "full" ) {
90- try {
91- const months = CONFIG . time ?. worldCalendarConfig ?. months ?. values ?? [ ] ;
92- const m = months [ monthIndex ] ;
93- if ( ! m ) return null ;
94- const raw = form === "abbr"
95- ? ( m . abbreviation ?? m . name ?? null )
96- : ( m . name ?? m . abbreviation ?? null ) ;
97- if ( raw == null ) return null ;
98- return typeof raw === "string" ? game . i18n . localize ( raw ) : String ( raw ) ;
99- } catch ( e ) {
100- return null ;
101- }
102- }
10382
10483/**
10584 * Format a seconds timestamp for a given vis.js axis scale.
@@ -122,31 +101,23 @@ function calendarMonthName(monthIndex, form = "full") {
122101function fgFormatForScale ( seconds , scale , role ) {
123102 console . log ( seconds , scale , role )
124103 try {
125- const cal = game ?. time ?. calendar ;
126- if ( ! cal ?. timeToComponents ) {
127- // No calendar API: fall back to the raw calendar.format() or the number
128- return cal ?. format ? cal . format ( seconds ) : String ( seconds ) ;
129- }
130-
131- //const c = cal.timeToComponents(seconds);
132- const c = game . time . calendar . constructor . dateFormattingParts ( game . time . calendar , game . time . calendar . timeToComponents ( seconds ) )
133- // c: { year, month (0-based), dayOfMonth (0-based), hour, minute, second }
134-
135- /*
136- const year = c.year ?? 0;
137- const month = c.month ?? 0; // 0-based
138- const day = (c.dayOfMonth ?? 0) + 1; // make 1-based for display
139- const hour = String(c.hour ?? 0).padStart(2, "0");
140- const min = String(c.minute ?? 0).padStart(2, "0");
141- */
142- const year = c . y ?? 0 ;
143- const month = c . m ?? 0 ; // 0-based
144- const day = ( c . d ?? 0 ) + 1 ; // make 1-based for display
145- const hour = c . H ;
146- const min = c . M ;
147-
148- const monthFull = c . B ;
149- const monthAbbr = c . B ;
104+ const parts = getCalendarDateParts ( seconds ) ;
105+ if ( ! parts ) return String ( seconds ) ;
106+
107+ const {
108+ year,
109+ monthIndex,
110+ monthOrdinal,
111+ monthName,
112+ monthAbbreviation,
113+ day,
114+ hour,
115+ minute,
116+ second,
117+ hourPadded,
118+ minutePadded,
119+ secondPadded
120+ } = parts ;
150121
151122 switch ( scale ) {
152123 // ── Finest scales: we don't show sub-minute detail ──────────────────
@@ -157,27 +128,27 @@ function fgFormatForScale(seconds, scale, role) {
157128 // intentional fall-through
158129 case "minute" :
159130 return role === "major"
160- ? `${ day } ${ monthFull } ${ year } `
161- : `${ hour } :${ min } ` ;
131+ ? `${ day } ${ monthName } ${ year } `
132+ : `${ hour } :${ minute } ` ;
162133
163134 // ── Hour ─────────────────────────────────────────────────────────────
164135 case "hour" :
165136 return role === "major"
166- ? `${ day } ${ monthFull } ${ year } `
137+ ? `${ day } ${ monthName } ${ year } `
167138 : `${ hour } :00` ;
168139
169140 // ── Day / weekday ─────────────────────────────────────────────────────
170141 case "weekday" :
171142 case "day" :
172143 return role === "major"
173- ? `${ monthFull } ${ year } `
174- : `${ day } ${ monthAbbr } ` ;
144+ ? `${ monthName } ${ year } `
145+ : `${ day } ${ monthAbbreviation } ` ;
175146
176147 // ── Month ─────────────────────────────────────────────────────────────
177148 case "month" :
178149 return role === "major"
179150 ? String ( year )
180- : `${ monthFull } ${ year } ` ;
151+ : `${ monthName } ${ year } ` ;
181152
182153 // ── Year ──────────────────────────────────────────────────────────────
183154 case "year" :
@@ -253,29 +224,25 @@ function installMomentPatch() {
253224 * Always shows full date + time down to minutes: "DD MonthName Year HH:MM"
254225 */
255226function fgFormatFull ( seconds ) {
256- console . log ( seconds )
257227 try {
258- const cal = game ?. time ?. calendar ;
259- if ( ! cal ?. timeToComponents ) {
260- return cal ?. format ? cal . format ( seconds ) : String ( seconds ) ;
261- }
262- // const c = cal.timeToComponents(seconds);
263- const c = game . time . calendar . constructor . dateFormattingParts ( game . time . calendar , game . time . calendar . timeToComponents ( seconds ) )
264-
265- /*
266- const year = c.year ?? 0;
267- const month = c.month ?? 0;
268- const day = (c.dayOfMonth ?? 0) + 1;
269- const hour = String(c.hour ?? 0).padStart(2, "0");
270- const min = String(c.minute ?? 0).padStart(2, "0");
271- */
272- const year = c . y ?? 0 ;
273- const month = c . m ?? 0 ; // 0-based
274- const day = ( c . d ?? 0 ) + 1 ; // make 1-based for display
275- const hour = c . H ;
276- const min = c . M ;
277- const monthName = c . B ;
278- return `${ day } ${ monthName } ${ year } ${ hour } :${ min } ` ;
228+ const parts = getCalendarDateParts ( seconds ) ;
229+ if ( ! parts ) return String ( seconds ) ;
230+
231+ const {
232+ year,
233+ monthIndex,
234+ monthOrdinal,
235+ monthName,
236+ monthAbbreviation,
237+ day,
238+ hour,
239+ minute,
240+ second,
241+ hourPadded,
242+ minutePadded,
243+ secondPadded
244+ } = parts ;
245+ return `${ day } ${ monthName } ${ year } ${ hour } :${ minute } ` ;
279246 } catch ( e ) {
280247 return String ( seconds ) ;
281248 }
@@ -293,6 +260,54 @@ function buildVisAxisFormat() {
293260 return { minorLabels : minor , majorLabels : major } ;
294261}
295262
263+ function getCalendarDateParts ( seconds ) {
264+ const calendar = game ?. time ?. calendar ;
265+ if ( ! calendar ?. timeToComponents ) return null ;
266+
267+ const components = calendar . timeToComponents ( seconds ) ;
268+ const monthIndex = Number ( components . month ?? 0 ) ;
269+ const month = calendar . months ?. values ?. [ monthIndex ] ?? null ;
270+
271+ const localize = value => {
272+ if ( value == null ) return "" ;
273+ return typeof value === "string"
274+ ? game . i18n . localize ( value )
275+ : String ( value ) ;
276+ } ;
277+
278+ const rawYear = Number ( components . year ?? 0 ) ;
279+ const yearZero = Number ( calendar . years ?. yearZero ?? 0 ) ;
280+ const year = rawYear + ( Number . isFinite ( yearZero ) ? yearZero : 0 ) ;
281+
282+ const day = Number ( components . dayOfMonth ?? 0 ) + 1 ;
283+ const hour = Number ( components . hour ?? 0 ) ;
284+ const minute = Number ( components . minute ?? 0 ) ;
285+ const second = Number ( components . second ?? 0 ) ;
286+
287+ const monthName =
288+ localize ( month ?. name ) ||
289+ String ( month ?. ordinal ?? monthIndex + 1 ) ;
290+
291+ const monthAbbreviation =
292+ localize ( month ?. abbreviation ) ||
293+ monthName ;
294+
295+ return {
296+ year,
297+ monthIndex,
298+ monthOrdinal : month ?. ordinal ?? monthIndex + 1 ,
299+ monthName,
300+ monthAbbreviation,
301+ day,
302+ hour,
303+ minute,
304+ second,
305+ hourPadded : String ( hour ) . padStart ( 2 , "0" ) ,
306+ minutePadded : String ( minute ) . padStart ( 2 , "0" ) ,
307+ secondPadded : String ( second ) . padStart ( 2 , "0" )
308+ } ;
309+ }
310+
296311// ---------------------------------------------------------------------------
297312// VisTimelineRenderer
298313// ---------------------------------------------------------------------------
@@ -347,6 +362,8 @@ export class VisTimelineRenderer extends BaseRenderer {
347362 return false ;
348363 }
349364
365+
366+
350367 get instructions ( ) {
351368 return t ( "VisTimeline.Instructions" ) ;
352369 }
0 commit comments