4人参与 • 2026-08-07 • Java
| 类别 | 版本 |
|---|---|
| c# | 12 (.net 8) |
| java | 17 (lts) |
| spring boot | 3.2.x |
| mybatis-plus | 3.5.9 |
| c# | java | 特点 |
|---|---|---|
datetime | localdatetime | 不含时区,日期 + 时间 |
datetimeoffset | offsetdatetime | 含 utc 偏移量 |
datetime.utcnow | instant | utc 时间戳(瞬时点) |
datetime + timezoneinfo | zoneddatetime | 带时区规则的完整时间 |
timespan | duration | 时间跨度 |
dateonly (.net 6+) | localdate | 仅日期 |
timeonly (.net 6+) | localtime | 仅时间 |
java 17 推荐:instant(时间戳)/ localdatetime(本地时间)/ zoneddatetime(带时区)是业内经验中覆盖绝大多数业务场景的三类时间类型,避免使用已过时的 java.util.date 与 calendar。对于仅日期或仅时间的场景,分别使用 localdate 和 localtime。

// java 17 时间 api(推荐 java.time)
import java.time.instant;
import java.time.localdatetime;
import java.time.offsetdatetime;
import java.time.zoneddatetime;
import java.time.zoneid;
import java.time.localdate;
import java.time.localtime;
import java.time.format.datetimeformatter;
public class datetimeexample {
public static void main(string[] args) {
// 创建各种时间类型实例
instant now = instant.now();
localdatetime local = localdatetime.now();
offsetdatetime offset = offsetdatetime.now();
zoneddatetime shanghai = zoneddatetime.now(zoneid.of("asia/shanghai"));
localdate today = localdate.now();
localtime currenttime = localtime.now();
// 格式化(iso 8601:instant.tostring() 默认就是 iso 8601 格式)
string iso = now.tostring();
system.out.println("iso 8601 格式: " + iso);
// 解析
instant parsed = instant.parse("2026-08-02t12:00:00z");
system.out.println("解析后的时间: " + parsed);
// 其他示例
system.out.println("本地日期时间: " + local);
system.out.println("上海时区时间: " + shanghai);
system.out.println("仅日期: " + today);
system.out.println("仅时间: " + currenttime);
}
}import java.time.duration;
import java.time.period;
import java.time.zoneid;
import java.time.instant;
import java.time.localdatetime;
import java.time.zoneddatetime;
import java.time.localdate;
import java.time.format.datetimeformatter;
public class commonoperationsexample {
public static void main(string[] args) {
// 创建特定时间
localdatetime specifictime = localdatetime.of(2026, 8, 5, 14, 30, 0);
instant specificinstant = instant.parse("2026-08-05t06:30:00z");
system.out.println("特定时间: " + specifictime);
system.out.println("特定时间戳: " + specificinstant);
// 时间计算
localdatetime tomorrow = localdatetime.now().plusdays(1);
instant onehourlater = instant.now().plus(duration.ofhours(1));
system.out.println("明天: " + tomorrow);
system.out.println("一小时后: " + onehourlater);
// 时区转换
zoneddatetime utctime = zoneddatetime.now(zoneid.of("utc"));
zoneddatetime newyorktime = utctime.withzonesameinstant(zoneid.of("america/new_york"));
system.out.println("utc时间: " + utctime);
system.out.println("纽约时间: " + newyorktime);
// 时间间隔
localdatetime starttime = localdatetime.of(2026, 8, 5, 9, 0, 0);
localdatetime endtime = localdatetime.of(2026, 8, 5, 17, 30, 0);
duration duration = duration.between(starttime, endtime);
system.out.println("工作时间间隔: " + duration.tohours() + "小时");
// 日期间隔
localdate startdate = localdate.of(2026, 1, 1);
localdate enddate = localdate.of(2026, 12, 31);
period period = period.between(startdate, enddate);
system.out.println("日期间隔: " + period.getyears() + "年" +
period.getmonths() + "月" + period.getdays() + "天");
}
}using system;
using system.globalization;
public class commonoperationsexample
{
public static void main(string[] args)
{
// 创建特定时间
datetime specifictime = new datetime(2026, 8, 5, 14, 30, 0);
datetimeoffset specificoffset = new datetimeoffset(2026, 8, 5, 14, 30, 0, timespan.fromhours(8));
console.writeline($"特定时间: {specifictime}");
console.writeline($"特定时间偏移: {specificoffset}");
// 时间计算
datetime tomorrow = datetime.now.adddays(1);
datetimeoffset onehourlater = datetimeoffset.utcnow.addhours(1);
console.writeline($"明天: {tomorrow}");
console.writeline($"一小时后: {onehourlater}");
// 时区转换
timezoneinfo chinazone = timezoneinfo.findsystemtimezonebyid("china standard time");
datetime utctime = datetime.utcnow;
datetime chinatime = timezoneinfo.converttimefromutc(utctime, chinazone);
console.writeline($"utc时间: {utctime}");
console.writeline($"中国时间: {chinatime}");
// 时间间隔
datetime starttime = new datetime(2026, 8, 5, 9, 0, 0);
datetime endtime = new datetime(2026, 8, 5, 17, 30, 0);
timespan timespan = endtime - starttime;
console.writeline($"工作时间间隔: {timespan.totalhours}小时");
// 日期间隔
dateonly startdate = new dateonly(2026, 1, 1);
dateonly enddate = new dateonly(2026, 12, 31);
int daysbetween = enddate.daynumber - startdate.daynumber;
console.writeline($"日期间隔: {daysbetween}天");
}
}
| 操作 | java (java.time) | c# (.net) |
|---|---|---|
| 创建时间 | localdatetime.of() | new datetime() |
| 解析字符串 | localdatetime.parse() | datetime.parse() |
| 格式化 | datetimeformatter | tostring() |
| 时区转换 | withzonesameinstant() | timezoneinfo.converttime() |
| 时间计算 | plusdays() / minushours() | adddays() / addhours() |
| 时间间隔 | duration / period | timespan |
跨语言(前后端 / 跨服务)序列化时,统一用 utc + iso 8601 字符串。避免直接传 datetime.now(带本地时区)导致接收方误判。
| 注意事项 | 说明 |
|---|---|
| 统一 utc | 数据库 / 消息队列 / api 一律用 utc;展示层再转本地时区 |
| iso 8601 字符串 | 例:2026-08-02t12:00:00z,自描述、可读、跨语言无歧义 |
| java jackson | spring.jackson.time-zone=utc、spring.jackson.date-format=yyyy-mm-dd't'hh:mm:ss'z' |
| c# json | system.text.json 配置:jsonserializeroptions { propertynamingpolicy = jsonnamingpolicy.camelcase, converters = { new jsonstringenumconverter() } },默认序列化 datetime 和 datetimeoffset 为 iso 8601 格式。如需强制 utc,可使用 jsonconverter 或确保数据源为 utc。 |
| 数据库 | postgresql 用 timestamp with time zone、mysql 用 datetime + 应用层统一 utc |
| 时区存储 | 数据库额外存储时区信息(如 zone_id 列),用于展示层转换 |
日期时间与字符串之间的相互转换是日常开发中的高频操作。java 的 java.time.format.datetimeformatter 与 c# 的 datetime.tostring() / datetime.parse() 提供了丰富的格式化与解析能力。
import java.time.localdatetime;
import java.time.zoneddatetime;
import java.time.instant;
import java.time.zoneid;
import java.time.format.datetimeformatter;
import java.time.format.datetimeparseexception;
import java.time.format.formatstyle;
import java.util.locale;
public class formatparseexample {
public static void main(string[] args) {
// 1. 预定义格式器(iso 标准)
instant instant = instant.now();
string isostring = instant.tostring(); // "2026-08-04t15:57:18.123z"
instant parsedinstant = instant.parse(isostring);
system.out.println("iso 8601格式: " + isostring);
system.out.println("解析后的时间戳: " + parsedinstant);
// 2. 自定义格式器
datetimeformatter formatter = datetimeformatter.ofpattern("yyyy-mm-dd hh:mm:ss");
localdatetime now = localdatetime.now();
// 格式化:日期时间 → 字符串
string formatted = now.format(formatter); // "2026-08-04 23:57:18"
system.out.println("自定义格式: " + formatted);
// 解析:字符串 → 日期时间
localdatetime parsed = localdatetime.parse("2026-08-04 23:57:18", formatter);
system.out.println("解析后的时间: " + parsed);
// 3. 带时区的格式化
datetimeformatter zonedformatter = datetimeformatter.ofpattern("yyyy-mm-dd hh:mm:ss z");
zoneddatetime zoned = zoneddatetime.now();
string zonedstring = zoned.format(zonedformatter); // "2026-08-04 23:57:18 cst"
system.out.println("带时区格式: " + zonedstring);
// 4. 本地化格式
datetimeformatter localizedformatter = datetimeformatter.oflocalizeddatetime(formatstyle.medium)
.withlocale(locale.china);
string localized = now.format(localizedformatter); // "2026年8月4日 下午11:57:18"
system.out.println("本地化格式: " + localized);
// 5. 错误处理
try {
localdatetime invalid = localdatetime.parse("2026-13-45 25:61:99", formatter);
system.out.println("无效时间: " + invalid);
} catch (datetimeparseexception e) {
system.err.println("解析失败: " + e.getmessage());
}
}
}using system;
using system.globalization;
public class formatparseexample
{
public static void main(string[] args)
{
// 1. 标准格式字符串
datetime utcnow = datetime.utcnow;
string isostring = utcnow.tostring("o"); // iso 8601: "2026-08-04t15:57:18.1234567z"
string rfc1123 = utcnow.tostring("r"); // rfc 1123: "thu, 04 aug 2026 15:57:18 gmt"
console.writeline($"iso 8601格式: {isostring}");
console.writeline($"rfc 1123格式: {rfc1123}");
// 2. 自定义格式字符串
datetime localnow = datetime.now;
string customformat = localnow.tostring("yyyy-mm-dd hh:mm:ss"); // "2026-08-04 23:57:18"
string chineseformat = localnow.tostring("yyyy年m月d日 hh时mm分ss秒"); // "2026年8月4日 23时57分18秒"
console.writeline($"自定义格式: {customformat}");
console.writeline($"中文格式: {chineseformat}");
// 3. 解析字符串
datetime parsed1 = datetime.parse("2026-08-04 23:57:18");
console.writeline($"解析结果1: {parsed1}");
datetime parsed2 = datetime.parseexact("04/08/2026 23:57", "dd/mm/yyyy hh:mm", cultureinfo.invariantculture);
console.writeline($"解析结果2: {parsed2}");
// 4. 带时区信息的 datetimeoffset
datetimeoffset offsetnow = datetimeoffset.utcnow;
string offsetstring = offsetnow.tostring("yyyy-mm-ddthh:mm:sszzz"); // "2026-08-04t15:57:18+00:00"
console.writeline($"带时区偏移格式: {offsetstring}");
// 5. 使用 cultureinfo 本地化
cultureinfo chinaculture = new cultureinfo("zh-cn");
string localized = localnow.tostring("f", chinaculture); // "2026年8月4日 23:57:18"
console.writeline($"本地化完整格式: {localized}");
// 6. 错误处理 - 使用 tryparse 避免异常
string invaliddatestr = "2026-13-45 25:61:99";
if (datetime.tryparse(invaliddatestr, out datetime validdate))
{
console.writeline($"解析成功: {validdate}");
}
else
{
console.writeline($"解析失败: 字符串 '{invaliddatestr}' 不是有效的 datetime");
}
// 7. 使用 tryparseexact 进行精确解析
string exactdatestr = "2026-08-04 23:57:18";
if (datetime.tryparseexact(exactdatestr, "yyyy-mm-dd hh:mm:ss",
cultureinfo.invariantculture, datetimestyles.none, out datetime exactdate))
{
console.writeline($"精确解析成功: {exactdate}");
}
else
{
console.writeline($"精确解析失败: 字符串 '{exactdatestr}' 不符合指定格式");
}
}
}
| 场景 | java 17 (java.time) | c# 12 (.net 8) | 说明 |
|---|---|---|---|
| iso 8601 格式 | instant.tostring() / instant.parse() | datetime.tostring("o") / datetime.parse() | 跨语言通信首选 |
| 数据库时间格式 | localdatetime.format(datetimeformatter.iso_local_date_time) | datetime.tostring("yyyy-mm-dd hh:mm:ss") | mysql datetime 格式 |
| 前端展示格式 | zoneddatetime.format(datetimeformatter.ofpattern("yyyy-mm-dd hh:mm:ss z")) | datetime.tostring("yyyy-mm-dd hh:mm:ss zzz") | 带时区信息 |
| 仅日期 | localdate.format(datetimeformatter.iso_local_date) | dateonly.tostring("yyyy-mm-dd") | 生日、纪念日等 |
| 仅时间 | localtime.format(datetimeformatter.iso_local_time) | timeonly.tostring("hh:mm:ss") | 营业时间、会议时间 |
| 错误处理 | datetimeparseexception | formatexception | 解析失败时捕获异常 |
重用 formatter 实例:datetimeformatter 和格式字符串解析都是线程安全的,应创建静态实例重用:
// java - 类级别定义
public class datetimeutils {
private static final datetimeformatter custom_formatter =
datetimeformatter.ofpattern("yyyy-mm-dd hh:mm:ss");
public static string formatdatetime(localdatetime datetime) {
return datetime.format(custom_formatter);
}
public static localdatetime parsedatetime(string text) {
return localdatetime.parse(text, custom_formatter);
}
}// c# - 类级别定义
public static class datetimeutils
{
private static readonly string customformat = "yyyy-mm-dd hh:mm:ss";
private static readonly cultureinfo invariantculture = cultureinfo.invariantculture;
public static string formatdatetime(datetime datetime)
{
return datetime.tostring(customformat, invariantculture);
}
public static datetime parsedatetime(string text)
{
return datetime.parseexact(text, customformat, invariantculture);
}
}
避免频繁解析:对于高频转换,考虑缓存解析结果或使用对象池。
使用 tryparse 避免异常:
// java - 使用 try-catch
public class safeparser {
private static final datetimeformatter formatter =
datetimeformatter.ofpattern("yyyy-mm-dd hh:mm:ss");
public static optional<localdatetime> tryparse(string text) {
try {
localdatetime result = localdatetime.parse(text, formatter);
return optional.of(result);
} catch (datetimeparseexception e) {
return optional.empty();
}
}
}// c# - 使用 tryparse/tryparseexact
using system.globalization;
public static class safeparser
{
private static readonly string customformat = "yyyy-mm-dd hh:mm:ss";
private static readonly cultureinfo invariantculture = cultureinfo.invariantculture;
public static bool tryparsedatetime(string text, out datetime result)
{
return datetime.tryparse(text, out result);
}
public static bool tryparseexactdatetime(string text, out datetime result)
{
return datetime.tryparseexact(text, customformat,
invariantculture, datetimestyles.none, out result);
}
}
localdatetime 和 datetime(未指定 kind)不含时区信息,序列化到不同时区环境会出错。zoneddatetime 和 datetime 带 datetimekind.local 会自动处理夏令时,但跨时区计算时仍需谨慎。yyyy(年) vs yyyy(周年年),mm(月) vs mm(分),大小写敏感。datetimeformatter 实例或使用复杂正则表达式解析会导致性能下降。javatimemodule 序列化 instant 为 iso-8601 字符串(如 2026-08-03t12:00:00z)。前端用 new date(...) 解析,再 tolocalestring() 按用户时区展示。spring boot 3.2 默认配置 spring.jackson.serialization.write_dates_as_timestamps=false,输出 iso 字符串。以上就是c#与java在日期时间处理方面的差异对比详解的详细内容,更多关于c#与java日期时间处理对比的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论