1+ // ---- Helpers ----
2+ const loadVariable = ( key , defaultValue ) => {
3+ const value = RainmeterAPI . GetVariable ( String ( key ) ) ;
4+ if ( value . includes ( "#" ) ) {
5+ writeVariable ( String ( key ) , String ( defaultValue ) ) ;
6+ return String ( defaultValue ) ;
7+ }
8+ return value ;
9+ } ;
10+
11+ const writeVariable = ( key , value ) => {
12+ RainmeterAPI . Bang ( `[!WriteKeyValue Variables "${ key } " "${ value } "]` ) ;
13+ } ;
14+
115const date = new Date ( ) ;
16+ const userLocale = Intl . DateTimeFormat ( ) . resolvedOptions ( ) . locale ;
17+
18+ let locale = loadVariable ( 'locale' , userLocale ) ;
19+
20+ function toggleLocale ( ) {
21+ locale = locale === userLocale ? 'en-US' : userLocale ;
22+ writeVariable ( 'locale' , locale ) ;
23+ renderWeekdays ( ) ;
24+ renderCalendar ( ) ;
25+ }
26+
27+ const renderWeekdays = ( ) => {
28+ const weekdaysContainer = document . querySelector ( ".weekdays" ) ;
29+ weekdaysContainer . innerHTML = "" ;
30+
31+ const baseDate = new Date ( Date . UTC ( 2026 , 0 , 5 ) ) ; // Sunday
32+
33+ const formatter = new Intl . DateTimeFormat ( locale , {
34+ weekday : 'short'
35+ } ) ;
36+
37+ for ( let i = 0 ; i < 7 ; i ++ ) {
38+ const day = new Date ( baseDate ) ;
39+ day . setUTCDate ( baseDate . getUTCDate ( ) + i ) ;
40+
41+ const name = formatter . format ( day ) ;
42+ weekdaysContainer . innerHTML += `<span>${ name } </span>` ;
43+ }
44+ } ;
245
346const renderCalendar = ( ) => {
4- date . setDate ( 1 ) ;
5-
6- const monthDays = document . querySelector ( ".days" ) ;
7-
8- const lastDay = new Date (
9- date . getFullYear ( ) ,
10- date . getMonth ( ) + 1 ,
11- 0
12- ) . getDate ( ) ;
13-
14- const prevLastDay = new Date (
15- date . getFullYear ( ) ,
16- date . getMonth ( ) ,
17- 0
18- ) . getDate ( ) ;
19-
20- const firstDayIndex = date . getDay ( ) ;
21-
22- const lastDayIndex = new Date (
23- date . getFullYear ( ) ,
24- date . getMonth ( ) + 1 ,
25- 0
26- ) . getDay ( ) ;
27-
28- const nextDays = 7 - lastDayIndex - 1 ;
29-
30- const months = [
31- "January" , "February" , "March" , "April" , "May" , "June" ,
32- "July" , "August" , "September" , "October" , "November" , "December"
33- ] ;
34-
35- document . querySelector ( "#current-month" ) . innerHTML = months [ date . getMonth ( ) ] ;
36- document . querySelector ( "#current-year" ) . innerHTML = date . getFullYear ( ) ;
37-
38- let days = "" ;
39-
40- // Previous month's days
41- for ( let x = firstDayIndex ; x > 0 ; x -- ) {
42- days += `<div class="prev-date">${ prevLastDay - x + 1 } </div>` ;
43- }
44-
45- // Current month's days
46- for ( let i = 1 ; i <= lastDay ; i ++ ) {
47- if (
48- i === new Date ( ) . getDate ( ) &&
49- date . getMonth ( ) === new Date ( ) . getMonth ( ) &&
50- date . getFullYear ( ) === new Date ( ) . getFullYear ( )
51- ) {
52- days += `<div class="today">${ i } </div>` ;
53- } else {
54- days += `<div>${ i } </div>` ;
55- }
56- }
57-
58- // Next month's days
59- for ( let j = 1 ; j <= nextDays ; j ++ ) {
60- days += `<div class="next-date">${ j } </div>` ;
61- }
62-
63- monthDays . innerHTML = days ;
47+ date . setDate ( 1 ) ;
48+
49+ const monthDays = document . querySelector ( ".days" ) ;
50+
51+ const lastDay = new Date (
52+ date . getFullYear ( ) ,
53+ date . getMonth ( ) + 1 ,
54+ 0
55+ ) . getDate ( ) ;
56+
57+ const prevLastDay = new Date (
58+ date . getFullYear ( ) ,
59+ date . getMonth ( ) ,
60+ 0
61+ ) . getDate ( ) ;
62+
63+ const firstDayIndex =
64+ ( new Intl . DateTimeFormat ( locale , { weekday : 'short' } )
65+ . formatToParts ( date )
66+ . find ( p => p . type === 'weekday' ) ? date . getDay ( ) : date . getDay ( ) ) ;
67+
68+ const lastDayIndex = new Date (
69+ date . getFullYear ( ) ,
70+ date . getMonth ( ) + 1 ,
71+ 0
72+ ) . getDay ( ) ;
73+
74+ const nextDays = 7 - lastDayIndex - 1 ;
75+
76+ // Localized month name
77+ const monthFormatter = new Intl . DateTimeFormat ( locale , { month : 'long' } ) ;
78+
79+ document . querySelector ( "#current-month" ) . textContent =
80+ monthFormatter . format ( date ) ;
81+
82+ document . querySelector ( "#current-year" ) . textContent =
83+ date . getFullYear ( ) ;
84+
85+ let days = "" ;
86+
87+ // Previous month's days
88+ for ( let x = firstDayIndex ; x > 0 ; x -- ) {
89+ days += `<div class="prev-date">${ prevLastDay - x + 1 } </div>` ;
90+ }
91+
92+ // Current month's days
93+ const today = new Date ( ) ;
94+
95+ for ( let i = 1 ; i <= lastDay ; i ++ ) {
96+ if (
97+ i === today . getDate ( ) &&
98+ date . getMonth ( ) === today . getMonth ( ) &&
99+ date . getFullYear ( ) === today . getFullYear ( )
100+ ) {
101+ days += `<div class="today">${ i } </div>` ;
102+ } else {
103+ days += `<div>${ i } </div>` ;
104+ }
105+ }
106+
107+ // Next month's days
108+ for ( let j = 1 ; j <= nextDays ; j ++ ) {
109+ days += `<div class="next-date">${ j } </div>` ;
110+ }
111+
112+ monthDays . innerHTML = days ;
64113} ;
65114
66115document . querySelector ( "#prev-month" ) . addEventListener ( "click" , ( ) => {
@@ -73,4 +122,5 @@ document.querySelector("#next-month").addEventListener("click", () => {
73122 renderCalendar ( ) ;
74123} ) ;
75124
125+ renderWeekdays ( ) ;
76126renderCalendar ( ) ;
0 commit comments