You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何将NTP(网络时间协议)时间设为日历初始时间?

Flutter日历选择器改用NTP标准时间方案

当前你的日历选择类依赖设备本地UTC时间,若用户修改设备时间会导致初始日期、可选日期判断失效。以下是修改后的完整代码,改用NTP服务器获取标准UTC时间:

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:ntp/ntp.dart';

import '../widget/colors.dart';

class SelectDateFromCalender {
  String? date;
  SelectDateFromCalender._internal();

  static final SelectDateFromCalender _instance =
      SelectDateFromCalender._internal();

  static SelectDateFromCalender get instance => _instance;

  selectDate(BuildContext context) async {
    // 获取NTP标准UTC时间,失败时回退到本地UTC时间
    final DateTime ntpUtcTime = await _getNtpUtcTime();

    DateTime? newDate = await showDatePicker(
      context: context,
      initialDate: ntpUtcTime, // 使用NTP时间作为初始日期
      firstDate: DateTime(1900).toUtc(),
      lastDate: DateTime(2040),
      helpText: 'Select Date',
      cancelText: "CANCEL",
      confirmText: "SAVE",
      initialDatePickerMode: DatePickerMode.day,
      selectableDayPredicate: (day) => _decideWhichDayToEnable(day, ntpUtcTime), // 基于NTP时间判断可选日期
      builder: (context, child) {
        return Theme(
          data: Theme.of(context).copyWith(
            textButtonTheme: TextButtonThemeData(
              style: TextButton.styleFrom(
                primary: colorPrimary, // button text color
              ),
            ),
          ),
          child: child!,
        );
      },
    );
    
    if (newDate != null) {
      date = DateFormat('dd-MM-yyyy').format(newDate);
    }
    return date;
  }

  bool _decideWhichDayToEnable(DateTime day, DateTime ntpUtcTime) {
    // 基于NTP标准时间限制可选日期范围
    return day.isAfter(ntpUtcTime.subtract(const Duration(days: 36500))) &&
           day.isBefore(ntpUtcTime.add(const Duration(days: 0)));
  }

  /// 获取NTP标准UTC时间,失败时回退到本地UTC时间
  Future<DateTime> _getNtpUtcTime({String lookupAddress = 'time.google.com'}) async {
    try {
      final DateTime ntpTime = await NTP.now(lookUpAddress: lookupAddress);
      return ntpTime.toUtc();
    } catch (e) {
      print('NTP时间获取失败: $e');
      return DateTime.now().toUtc();
    }
  }
}

关键改动说明

  • 新增_getNtpUtcTime方法:统一处理NTP时间获取逻辑,加入异常捕获,确保获取失败时功能仍可用(回退到本地时间)。
  • 替换初始日期:将showDatePicker的initialDate参数从本地UTC时间改为NTP标准时间。
  • 修正可选日期判断:将_decideWhichDayToEnable的判断基准从本地时间改为NTP时间,避免用户修改设备时间后可选范围异常。
  • 增加空值判断:处理用户取消日期选择的场景,防止newDate为null导致的崩溃。

内容的提问来源于stack exchange,提问作者wolfsoft Developer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:01:13