参考文章:
- Date与时间戳的相互转换(Java)
- Calendar是日历提供程序里的类:日历提供程序概览 | Android 开发者, 最低是14+版本,现在适配基本20几起,一般都兼容的;6.0以上记得动态权限申请;
一、时间戳
1999-02-20 12:22:22 -> yyyy-MM-dd HH:mm:ss
用Date类型包裹真的很重要: date.setTime(date.getTime() + (8 - hours) * 60 * 60 * 1000);
1、获取时间戳
1、当前时间戳,1970-1-01 00:00:00.000 到当前时刻的时间距离,类型为long
- 获取到的是13位毫秒,例如1704440617582
- 某些接口返回的是10位数s,所以方法要*1000
System.currentTimeMillis();
new Date().getTime();
Calendar.getInstance().getTimeInMillis();
2、通过时间戳和SimpleDateFormat获取对应年月日
参考: System.currentTimeMillis()与日期之间的相互转换
- 通过SimpleDateFormat(“yyyy-MM-dd HH:mm:ss.SSS”) 单独选取几点几分也行;用的是13位毫秒级;
- 设置Locale.getDefault() 有意思 中文是1月21 英文是mon 21
- 好用调用: private var mCurrentDay = SimpleDateFormat("yyyy-MM-dd").format(Date())
样例:
public static String getDayAndMoon(Long time) {
Date date = new Date(time);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm", Locale.getDefault());
return sdf.format(date);
}
3、Android APP首次启动/首次今日启动判断_判断是否为【单个自然日第一次启动】
- 思路是把上次和这次的年月日进行对比 Android中Calendar类的用法总结_android icalendar
4、时区转换 sdf.setTimeZone(localTimeZone);
- setTimeZone不设置的话默认是本机所在的时区
- 样例
// 创建一个 SimpleDateFormat 对象,用于格式化日期和时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
// 设置输入日期和时间的时区为太平洋标准时间
sdf.setTimeZone(TimeZone.getTimeZone("PST"));
// 创建一个 Date 对象,表示太平洋标准时间
Date pacificTime = new Date();
// 获取当前手机所在的时区
TimeZone localTimeZone = TimeZone.getDefault();
// 设置 SimpleDateFormat 对象的时区为当前手机所在的时区
sdf.setTimeZone(localTimeZone);
// 使用 SimpleDateFormat 对象将太平洋标准时间转换为手机当前时区的时间
String localTime = sdf.format(pacificTime);
// 输出转换后的时间
System.out.println("Local Time: " + localTime);
//用Data包裹
public static String getTime(Long time) {
Date date = new Date(time * 1000);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm", Locale.getDefault());
return sdf.format(date);
}
//设置显示格式
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd", Locale.ENGLISH);
二、日历相关
1、详解:Android向系统日历添加日程提醒事件_android 日历提前通知
- 如果是12小时制,日历也会正常添加
- 根据条件修改时间戳,好用
- getHours()失效的解决方案:关于日期:Java getHours(),getMinutes()和getSeconds()
private static long transformTargetTime(long reminderTime) {
// 创建一个 SimpleDateFormat 对象,用于格式化日期和时间
Log.d("yeTest", "当前时间戳 毫秒: "+reminderTime);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Log.d("yeTest", "transformTargetTime 原本时间: "+sdf.format(reminderTime));
Date date = new Date(reminderTime);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
//Date的gethour过期了,需要使用Calendar
int hours = calendar.get(Calendar.HOUR_OF_DAY);
if (hours < 8) {
date.setTime(date.getTime() + (8 - hours) * 60 * 60 * 1000); // Add the difference in hours
}
Log.d("yeTest", "转换时间戳 毫秒: "+date.getTime());
Log.d("yeTest", "transformTargetTime 原本时间: "+sdf.format(date.getTime()));
return date.getTime();
}
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
private void requestPermissionCalendar(int tag) {
if (getContext() != null && getActivity() != null) {
// 如果没有权限,则请求权限
xxFragment.this.requestPermissions(new String[]{Manifest.permission.WRITE_CALENDAR, Manifest.permission.READ_CALENDAR},
tag);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (requestCode == StaticVariables.REQUEST_TAG_1) {
//TAG_EVENT1
} else if (requestCode == StaticVariables.REQUEST_TAG_2) {
//TAG_EVENT2
}
}
}
三、消息提醒
1、Android13新特性之通知权限提升_android 通知权限
2、通知栏 Android Notification使用
- 自测设置高度无效,待跟进
3、Chat获取代码样例;Android13往上默认是开的
//这个xml清单文件声明,android13往上不写这个跳转设置页后也是打不开权限的,12的没写没关系,能打开
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
private static final int NOTIFICATION_PERMISSION_REQUEST_CODE = 1001;
// 检查是否已经获得通知权限
private boolean isNotificationPermissionGranted() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// 适用于Android O及以上版本
return NotificationManagerCompat.from(this).getImportance() != NotificationManagerCompat.IMPORTANCE_NONE;
} else {
// 适用于Android N及以下版本
return NotificationManagerCompat.from(this).areNotificationsEnabled();
}
}
// 请求通知权限 判断是否获取通知权限用Blankj工具类也好
private void requestNotificationPermission() {
if (!isNotificationPermissionGranted()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent settingsIntent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
startActivity(settingsIntent);
} else {
Intent settingsIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.parse("package:" + getPackageName()));
startActivity(settingsIntent);
}
}
}
// 在合适的地方调用请求通知权限方法
requestNotificationPermission();
Chat 有意思的时间戳
1、 Date类型
mTargetDate = Calendar.getInstance().time
Log.d("yeTest", "当天日期: "+mTargetDate)
当天日期: Mon Dec 09 11:30:30 GMT+08:00 2024
2、获取时间戳 System.currentTimeMillis();
Calendar calendar = Calendar.getInstance();
// 将当前时间增加30天
calendar.add(Calendar.DAY_OF_YEAR, 30);
// 获取增加30天后的时间
Calendar futureCalendar = calendar;
// 转换为时间戳(以毫秒为单位)
long futureTimestamp = futureCalendar.getTimeInMillis();
// 打印结果
System.out.println("当前时间:" + calendar.getTime());
System.out.println("增加30天后的时间:" + futureCalendar.getTime());
System.out.println("增加30天后的时间戳:" + futureTimestamp);
//当前时间:Wed Sep 01 15:30:00 UTC 2021
//增加30天后的时间:Fri Oct 01 15:30:00 UTC 2021
//增加30天后的时间戳:1633085400000
1、获取当前0点的时间戳
import java.util.Calendar;
public class Main {
public static void main(String[] args) {
// 获取当前时间的日期对象
Calendar calendar = Calendar.getInstance();
// 将时间部分设置为零时
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// 获取当天0点的时间戳
long timestamp = calendar.getTimeInMillis();
System.out.println("当天0点的时间戳: " + timestamp);
}
}
2、year、month 和 day 参数指定)与今天的0点之间的天数差。
import java.util.Calendar
fun calculateDaysDifference(year: Int, month: Int, day: Int): Long {
// 获取今天的0点时间
val today = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}
// 获取传入的日期的0点时间
val specifiedDate = Calendar.getInstance().apply {
set(year, month - 1, day) // month是从0开始的,所以要减1
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}
// 计算两个日期之间的差值,以天为单位
val differenceInMillis = today.timeInMillis - specifiedDate.timeInMillis
return differenceInMillis / (24 * 60 * 60 * 1000) // 转换为天数
}
3、判断给的时间戳是否为当天
fun isToday(timestamp: Long): Boolean {
// 获取当前时间的Calendar实例
val now = Calendar.getInstance()
// 获取给定时间戳的Calendar实例
val dateToCheck = Calendar.getInstance().apply {
timeInMillis = timestamp
}
// 检查年、月、日是否相同
return now.get(Calendar.YEAR) == dateToCheck.get(Calendar.YEAR) &&
now.get(Calendar.MONTH) == dateToCheck.get(Calendar.MONTH) &&
now.get(Calendar.DAY_OF_MONTH) == dateToCheck.get(Calendar.DAY_OF_MONTH)
}
4、时间戳转换
val now = Date()
val sdf = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
val formattedTime = sdf.format(now)
tvDrinkTip.text = formattedTime // 更新TextView内容
5、ms转小时
fun convertMsToHours(milliseconds: Long): String {
val hours = milliseconds.toDouble() / 3600000.0
return String.format("%.1f", hours)
}
6、生命周期内持续计时【24小时制】
mBindView.apply {
lifecycleScope.launch {
while (isActive) { // 当协程处在活跃状态时循环
val now = Date()
val sdf = SimpleDateFormat("HH:mm", Locale.getDefault())
val formattedTime = sdf.format(now)
tvTime.text = formattedTime // 更新TextView内容
delay(1000) // 等待一秒
}
}
}
7、获取当前小时数
// 使用Calendar获取当前小时
val calendar = Calendar.getInstance()
calendar.time = now
val hour = calendar.get(Calendar.HOUR_OF_DAY)
// 判断当前是否位于早上6点到晚上8点之间
if (hour in 6..20) {
println("白天")
} else {
println("非白天时间")
}
8、秒数转分钟
val time= stepTime/1000
val timeInMinutes = time / 60.0
val formattedTime = String.format("%.2f", timeInMinutes)
9、秒数转xx小时xx分钟
fun convertSecondsToHourMinuteFormat(seconds: Int): String {
if (seconds <= 0) return "0时1分" // 处理小于等于0秒的情况,按照问题中的要求显示至少1分钟
val minutes = seconds / 60
val hours = minutes / 60
val remainingMinutes = if (minutes % 60 == 0 && seconds % 60 != 0) {
1 // 如果没有额外的秒数达到下一个完整分钟,且确实有剩余秒数,则至少显示1分钟
} else {
minutes % 60
}
return "${hours}时${remainingMinutes}分"
}