如何利用SQLite存储的日期时间实现闹钟通知及存储规范咨询
问题分析与解决方案
我来帮你拆解这个问题,分成存储格式合理性和闹钟实现两部分来说:
一、日期时间存储格式合理性分析
你当前用的"03/31/18"(MM/DD/YY)和"6:50 AM"(12小时制)格式,存在几个明显的问题:
- 年份歧义:两位年份
18无法明确是2018还是1918,长期来看会有千年问题; - 格式兼容性差:
MM/DD/YY和全球多数地区使用的DD/MM/YYYY格式容易混淆,解析时极易出错; - 解析复杂度高:12小时制需要额外处理AM/PM转换,增加代码冗余和出错概率。
推荐的存储方式(二选一)
- ISO8601字符串格式:存储为
"YYYY-MM-DD HH:MM:SS"(例如"2018-03-31 06:50:00")- SQLite原生支持这种格式的排序、比较操作,无需额外处理;
- 几乎所有编程语言都有成熟的解析工具,兼容性拉满。
- Unix时间戳(整数):存储从
1970-01-01 00:00:00 UTC到目标时间的秒数/毫秒数- 计算时间差、排序的效率最高,完全不需要字符串解析;
- 唯一缺点是可读性差,但数据库存储优先考虑实用性的话,这是最优解。
二、获取数据并实现闹钟通知的步骤与示例
场景1:Python环境(桌面/脚本应用)
1. 从SQLite查询数据
import sqlite3 from datetime import datetime # 连接数据库 conn = sqlite3.connect("your_alarm_db.db") cursor = conn.cursor() # 查询所有闹钟记录 cursor.execute("SELECT date_col, time_col FROM alarm_table") alarm_records = cursor.fetchall() conn.close()
2. 解析日期时间字符串
alarm_datetimes = [] for date_str, time_str in alarm_records: # 组合日期和时间字符串 full_dt_str = f"{date_str} {time_str}" # 按现有格式解析为datetime对象 # %m=月份 %d=日期 %y=两位年份 %I=12小时制小时 %M=分钟 %p=AM/PM dt = datetime.strptime(full_dt_str, "%m/%d/%y %I:%M %p") # 手动修正年份(如果你的数据都是2000年后的) dt = dt.replace(year=dt.year + 2000) alarm_datetimes.append(dt)
3. 设置定时闹钟通知
用schedule库实现定时触发,结合系统通知组件:
import schedule import time from win10toast import ToastNotifier # Windows平台,Mac用pync,Linux用notify-send toaster = ToastNotifier() def trigger_alarm(): toaster.show_toast("闹钟提醒", "到点啦!", duration=10, icon_path="alarm_icon.ico") # 为每个闹钟设置定时任务 for dt in alarm_datetimes: schedule.every().day.at(dt.strftime("%H:%M")).do(trigger_alarm) # 保持程序运行 while True: schedule.run_pending() time.sleep(1)
场景2:Android环境(移动应用)
1. 查询数据库并解析日期时间
import java.time.LocalDateTime import java.time.format.DateTimeFormatter // 查询数据库 val db = SQLiteDatabase.openDatabase("your_alarm_db.db", null, SQLiteDatabase.OPEN_READONLY) val cursor = db.query("alarm_table", arrayOf("date_col", "time_col"), null, null, null, null, null) val alarmList = mutableListOf<LocalDateTime>() val formatter = DateTimeFormatter.ofPattern("MM/dd/yy h:mm a") while (cursor.moveToNext()) { val date = cursor.getString(cursor.getColumnIndexOrThrow("date_col")) val time = cursor.getString(cursor.getColumnIndexOrThrow("time_col")) val dtStr = "$date $time" val dt = LocalDateTime.parse(dtStr, formatter) alarmList.add(dt) } cursor.close() db.close()
2. 用AlarmManager设置系统闹钟
import android.app.AlarmManager import android.app.PendingIntent import android.content.Context import android.content.Intent // 自定义广播接收器,用于接收闹钟触发事件 class AlarmReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { // 这里构建并显示通知 val notificationManager = context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // 通知构建逻辑... } } // 设置单个闹钟的函数 fun setAlarm(context: Context, dt: LocalDateTime) { val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager val intent = Intent(context, AlarmReceiver::class.java) val pendingIntent = PendingIntent.getBroadcast( context, dt.hashCode(), intent, PendingIntent.FLAG_IMMUTABLE ) // 转换为系统可识别的时间戳 val triggerTime = dt.atZone(java.time.ZoneId.systemDefault()).toInstant().toEpochMilli() // 设置精确闹钟(支持后台休眠时触发) alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent) } // 遍历所有闹钟设置 alarmList.forEach { dt -> setAlarm(context, dt) }
内容的提问来源于stack exchange,提问作者Richard Denser
相关产品推荐
相关产品推荐

