1/** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import deviceInfo from '@ohos.deviceInfo'; 17import CommonEvent from '@ohos.commonEvent'; 18import CommonEventManager from '@ohos.commonEventManager'; 19import DateAndTimeModel from '../model/dateAndTimeImpl/DateAndTimeModel'; 20import LogUtil from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil'; 21import { BaseData } from '../../../../../../common/utils/src/main/ets/default/bean/BaseData'; 22import ConfigData from '../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData'; 23import HeadComponent from '../../../../../../common/component/src/main/ets/default/headComponent'; 24import ResourceUtil from '../../../../../../common/search/src/main/ets/default/common/ResourceUtil'; 25import DateAndTime from '../../../../../../common/utils/src/main/ets/default/baseUtil/DateAndTimeUtil'; 26import { DialogButtonLayout } from '../../../../../../common/component/src/main/ets/default/dialogComponent'; 27import { TextComponentWithEndText } from '../../../../../../common/component/src/main/ets/default/textComponent'; 28 29const MODULE_TAG = ConfigData.TAG + '.dateAndTime -> '; 30const deviceTypeInfo = deviceInfo.deviceType; 31 32class commonEvents { 33 events: string[] = [] 34} 35/** 36 * date and time 37 */ 38@Entry 39@Component 40struct dateAndTime { 41 @State dateAndTimeList: BaseData[] = []; 42 private date: string = ''; 43 private time: Resource | string = ''; 44 private image: string | Resource = ''; 45 private dateMark: string = 'date'; 46 private timeMark: string = 'time'; 47 private subscriber: CommonEventManager.CommonEventSubscriber | null = null; 48 private headName: string = ''; 49 50 private commonEventSubscribeInfo: commonEvents = { 51 events: [ 52 CommonEvent.Support.COMMON_EVENT_TIME_CHANGED, 53 CommonEvent.Support.COMMON_EVENT_TIMEZONE_CHANGED, 54 CommonEvent.Support.COMMON_EVENT_TIME_TICK, 55 CommonEvent.Support.COMMON_EVENT_DATE_CHANGED, 56 ] 57 }; 58 59 timeDialogController: CustomDialogController | null = new CustomDialogController({ 60 builder: TimeDialog24H({ action: this.onAccept }), 61 cancel: this.existApp, 62 autoCancel: true, 63 alignment: deviceTypeInfo === 'phone' || deviceTypeInfo === 'default' ? DialogAlignment.Bottom : DialogAlignment.Center, 64 offset: ({ dx: 0, dy: deviceTypeInfo === 'phone' || deviceTypeInfo === 'default' ? '-24dp' : 0 }), 65 }); 66 67 dateDialogController: CustomDialogController | null = new CustomDialogController({ 68 builder: DateDialog({ action: this.onAccept }), 69 cancel: this.existApp, 70 autoCancel: true, 71 alignment: deviceTypeInfo === 'phone' || deviceTypeInfo === 'default' ? DialogAlignment.Bottom : DialogAlignment.Center, 72 offset: ({ dx: 0, dy: deviceTypeInfo === 'phone' || deviceTypeInfo === 'default' ? '-24dp' : 0 }), 73 }); 74 75 build() { 76 Column() { 77 GridContainer({ gutter: ConfigData.GRID_CONTAINER_GUTTER_24, margin: ConfigData.GRID_CONTAINER_MARGIN_24 }) { 78 Column() { 79 HeadComponent({ headName: $r('app.string.dateAndTimeTab'), isActive: true }); 80 81 Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) { 82 Text($r('app.string.timeFormat')) 83 .fontSize($r('app.float.font_16')) 84 .fontColor($r('app.color.font_color_182431')) 85 .fontWeight(FontWeight.Medium) 86 .textAlign(TextAlign.Start) 87 .margin({ 88 top: $r("app.float.wh_value_4"), 89 bottom: $r("app.float.wh_value_4"), 90 left: $r("app.float.wh_value_12") 91 }) 92 93 Toggle({ type: ToggleType.Switch, isOn: this.is24hTimeFormat() }) 94 .margin({ right: $r('app.float.wh_value_6') }) 95 .width('36vp') 96 .height('20vp') 97 .selectedColor('#007DFF') 98 .onChange((isOn: boolean) => { 99 let timeFormat :boolean = this.is24hTimeFormat(); 100 LogUtil.info(MODULE_TAG + 'Toggle come onChange timeFormat ' + timeFormat); 101 if (this.is24hTimeFormat()) { 102 this.setTimeFormatAs12H(); 103 } else { 104 this.setTimeFormatAs24H(); 105 } 106 this.time = DateAndTime.getSystemTime(timeFormat); 107 this.changeValue(); 108 }); 109 } 110 .height($r('app.float.wh_value_56')) 111 .width(ConfigData.WH_100_100) 112 .backgroundColor($r("app.color.white_bg_color")) 113 .margin({ bottom: $r("app.float.wh_value_12"), top: $r("app.float.distance_8") }) 114 .borderRadius($r('app.float.radius_24')); 115 116 List() { 117 ForEach(this.dateAndTimeList, (item: BaseData) => { 118 ListItem() { 119 TextComponentWithEndText({ title: item.settingTitle, endText: item.settingValue?.toString(), clickEvent: () => { 120 LogUtil.info(MODULE_TAG + 'dialog come in' + JSON.stringify(item)); 121 if (item.settingAlias === 'date') { 122 LogUtil.info(MODULE_TAG + 'date dialog come in'); 123 this.dateDialogController?.open(); 124 } 125 if (item.settingAlias === 'time') { 126 LogUtil.info(MODULE_TAG + 'time dialog come in'); 127 this.timeDialogController?.open(); 128 } 129 } }); 130 } 131 }, (item: BaseData) => JSON.stringify(item)) 132 } 133 .padding($r('app.float.wh_value_4')) 134 .divider({ 135 strokeWidth: $r('app.float.divider_wh'), 136 color: $r('sys.color.ohos_id_color_list_separator'), 137 startMargin: $r('app.float.wh_value_15'), 138 endMargin: $r('app.float.wh_value_15') 139 }) 140 .borderRadius($r("app.float.radius_24")) 141 .backgroundColor($r("app.color.white_bg_color")) 142 .visibility(this.dateAndTimeList.length > 0 ? Visibility.Visible : Visibility.None) 143 } 144 .useSizeType({ 145 sm: { span: 4, offset: 0 }, 146 md: { span: 6, offset: 1 }, 147 lg: { span: 8, offset: 2 } 148 }) 149 } 150 .width(ConfigData.WH_100_100) 151 .height(ConfigData.WH_100_100); 152 } 153 .backgroundColor($r("sys.color.ohos_id_color_sub_background")) 154 .width(ConfigData.WH_100_100) 155 .height(ConfigData.WH_100_100) 156 } 157 158 /** 159 * Successfully built Dialog 160 */ 161 onAccept() { 162 LogUtil.info(MODULE_TAG + 'onAccept'); 163 } 164 165 /** 166 * Cancel Dialog 167 */ 168 existApp() { 169 LogUtil.info(MODULE_TAG + 'Cancel dialog!'); 170 } 171 172 /** 173 * modify date and time 174 */ 175 changeValue() { 176 this.dateAndTimeList = [ 177 { 178 settingSummary: '', 179 settingTitle: $r('app.string.date'), 180 settingValue: this.date, 181 settingAlias: this.dateMark, 182 settingArrow: this.image, 183 }, 184 { 185 settingSummary: '', 186 settingTitle: $r('app.string.time'), 187 settingValue: this.time, 188 settingAlias: this.timeMark, 189 settingArrow: this.image, 190 } 191 ] 192 } 193 194 aboutToAppear(): void { 195 this.image = "/res/image/ic_settings_arrow.svg"; 196 this.time = DateAndTime.getSystemTime(this.is24hTimeFormat()); 197 this.date = DateAndTime.getSystemDate(); 198 this.changeValue(); 199 this.getNowTime(); 200 DateAndTimeModel.registerObserver(this.getNowTime); 201 202 CommonEvent.createSubscriber(this.commonEventSubscribeInfo) 203 .then(subscriber => { 204 this.subscriber = subscriber; 205 CommonEvent.subscribe(this.subscriber, (error, commonEventData) => { 206 this.getNowTime(); 207 LogUtil.info(`${MODULE_TAG}, CommonEvent Subscribe callback in, error: ${error}, commonEventData: ${commonEventData}`); 208 }); 209 }); 210 } 211 212 /** 213 * get current system time 214 */ 215 private getNowTime(): void { 216 LogUtil.info(MODULE_TAG + 'get time come in'); 217 this.time = DateAndTime.getSystemTime(this.is24hTimeFormat()); 218 this.date = DateAndTime.getSystemDate(); 219 LogUtil.info(MODULE_TAG + 'get time end in date=' + this.date); 220 LogUtil.info(MODULE_TAG + 'get time end in time=' + this.time); 221 this.changeValue(); 222 } 223 224 aboutToDisappear(): void { 225 CommonEvent.unsubscribe(this.subscriber, (error, commonEventData) => { 226 LogUtil.info(`${MODULE_TAG}, CommonEvent unSubscribe callback in, error: ${error}, commonEventData: ${commonEventData}`); 227 DateAndTimeModel.unregisterObserver(); 228 }); 229 this.timeDialogController = null; 230 this.dateDialogController = null; 231 } 232 233 private setTimeFormatAs24H() { 234 DateAndTimeModel.setTimeFormatAs24H(); 235 } 236 237 private setTimeFormatAs12H() { 238 DateAndTimeModel.setTimeFormatAs12H(); 239 } 240 241 private is24hTimeFormat(): boolean { 242 let result = DateAndTimeModel.getTimeFormat(); 243 if (result === ConfigData.TIME_FORMAT_24) { 244 return true; 245 } 246 return false; 247 } 248} 249 250/** 251 * set time 24h format dialog 252 */ 253@CustomDialog 254@Component 255struct TimeDialog24H { 256 controller?: CustomDialogController; 257 action: () => void = () => {}; 258 private currentTimeString: string = ''; 259 private currentTimeDate: Date = new Date(); 260 private formatTime: string = ''; 261 262 build() { 263 Column() { 264 Column() { 265 Text($r('app.string.settingTime')) 266 .height($r('app.float.wh_value_56')) 267 .width(ConfigData.WH_100_100) 268 .textAlign(TextAlign.Center) 269 .fontSize($r('app.float.font_20')) 270 .fontColor($r("sys.color.ohos_id_color_primary")) 271 .fontWeight(FontWeight.Medium); 272 273 TimePicker({ selected: this.currentTimeDate }) 274 .useMilitaryTime(this.isNeedMilitaryTime()) 275 .onChange((date: TimePickerResult) => { 276 this.currentTimeString = DateAndTime.concatTime(date.hour, date.minute); 277 this.currentTimeDate.setHours(date.hour? date.hour : 0); 278 this.currentTimeDate.setMinutes(date.minute? date.minute : 0); 279 LogUtil.info(MODULE_TAG + 'onchange currentTimeString' + this.currentTimeString); 280 }) 281 .width(ConfigData.WH_100_100) 282 .height($r('app.float.wh_value_200')) 283 } 284 .padding({ left: $r('sys.float.ohos_id_max_padding_start'), right: $r('app.float.wh_value_21') }) 285 286 DialogButtonLayout({ 287 firstClickEvent: () => { 288 this.controller?.close(); 289 this.action(); 290 }, 291 secondClickEvent: () => { 292 LogUtil.info(MODULE_TAG + 'button confirm'); 293 let datetime = new Date(); 294 let y = datetime.getFullYear(); 295 let m = datetime.getMonth() + 1; 296 let d = datetime.getDate(); 297 this.formatTime = y + '-' + DateAndTime.fill(m) + '-' + DateAndTime.fill(d) 298 + 'T' + this.currentTimeString + ':' + '00'; 299 LogUtil.info(MODULE_TAG + 'onchange format time' + this.formatTime); 300 let s = (new Date(this.formatTime)).getTime(); 301 LogUtil.info('onchange time second' + s); 302 DateAndTimeModel.setTime(s); 303 this.controller?.close(); 304 this.action(); 305 } 306 }) 307 } 308 .width(ConfigData.WH_100_100) 309 } 310 311 private isNeedMilitaryTime(): boolean { 312 let result = DateAndTimeModel.getTimeFormat(); 313 // 24h time format need using military time 314 if (result === ConfigData.TIME_FORMAT_24) { 315 return true; 316 } 317 return false; 318 } 319} 320 321/** 322 * set date dialog 323 */ 324@CustomDialog 325@Component 326struct DateDialog { 327 controller?: CustomDialogController; 328 action: () => void = () => {}; 329 private minDate: Date = new Date('1970-01-01'); 330 private maxDate: Date = new Date('2037-12-31'); 331 private selectedDate: Date = this.initValidDate(); 332 @State date: string = ''; 333 @State day: string = ''; 334 335 build() { 336 Column() { 337 Column() { 338 Row() { 339 Text(this.date) 340 .fontSize($r('app.float.font_20')) 341 .fontWeight(500) 342 .fontColor($r("sys.color.ohos_id_color_primary")) 343 344 Text(this.day) 345 .fontSize($r('app.float.font_20')) 346 .fontWeight(500) 347 .fontColor($r("sys.color.ohos_id_color_primary")) 348 } 349 .height($r('app.float.wh_value_56')) 350 351 DatePicker({ start: this.minDate, end: this.maxDate, selected: this.selectedDate }) 352 .onChange((result: DatePickerResult) => { 353 let month = result.month ? result.month : 0; 354 let fmt = result.year + '-' + DateAndTime.fill(month + 1) + '-' + DateAndTime.fill(result.day); 355 this.selectedDate = new Date(fmt); 356 LogUtil.info(MODULE_TAG + 'onchange user select date fmt is : ' + fmt); 357 LogUtil.info(MODULE_TAG + 'onchange user select date is :' + this.selectedDate); 358 this.date = DateAndTime.concatDate(result.year, month + 1, result.day); 359 let resource = DateAndTime.convert(result.year, month + 1, result.day); 360 ResourceUtil.getString(resource).then(value => { 361 this.day = value; 362 LogUtil.info(MODULE_TAG + 'onchange refresh the show date is : ' + this.date); 363 LogUtil.info(MODULE_TAG + 'onchange refresh the show day is : ' + this.day); 364 }); 365 }) 366 .width(ConfigData.WH_100_100) 367 .height($r('app.float.wh_value_200')) 368 .padding({ right: $r('app.float.wh_37') }) 369 } 370 .padding({ left: $r('app.float.wh_padding_32'), right: $r('app.float.wh_padding_33') }) 371 372 DialogButtonLayout({ 373 firstClickEvent: () => { 374 this.controller?.close(); 375 this.action(); 376 }, 377 secondClickEvent: () => { 378 LogUtil.info(MODULE_TAG + 'start set date to : ' + this.selectedDate); 379 let sysTime = new Date(); 380 let fmt = this.selectedDate.getFullYear() + '-' + 381 DateAndTime.fill(this.selectedDate.getMonth() + 1) + '-' + 382 DateAndTime.fill(this.selectedDate.getDate()) + 'T' + 383 DateAndTime.fill(sysTime.getHours()) + ':' + 384 DateAndTime.fill(sysTime.getMinutes()) + ':' + 385 DateAndTime.fill(sysTime.getSeconds()); 386 LogUtil.info(MODULE_TAG + 'set date fmt is : ' + fmt); 387 let s = (new Date(fmt)).getTime(); 388 DateAndTimeModel.setTime(s); 389 this.controller?.close(); 390 this.action(); 391 } 392 }) 393 } 394 .width(ConfigData.WH_100_100); 395 } 396 397 aboutToAppear() { 398 let datetime = new Date(); 399 let y = datetime.getFullYear(); 400 let m = datetime.getMonth() + 1; 401 let d = datetime.getDate(); 402 this.date = DateAndTime.getSystemDate(); 403 ResourceUtil.getString(DateAndTime.convert(y, m, d)).then(value => { 404 this.day = value; 405 }); 406 } 407 408 private initValidDate() { 409 let sysDate = new Date(); 410 let sysDateTime = sysDate.getTime(); 411 LogUtil.info(MODULE_TAG + 'init sysDate is :' + sysDateTime); 412 if (sysDateTime < this.minDate.getTime()) { 413 return this.minDate; 414 } 415 if (sysDateTime > this.maxDate.getTime()) { 416 return this.maxDate; 417 } 418 return sysDate; 419 } 420}