修复时区展示
This commit is contained in:
@@ -1,40 +1,45 @@
|
||||
/**
|
||||
* Formats a Unix timestamp to a human-readable date string
|
||||
* @param timestamp - Unix timestamp in seconds
|
||||
* @param locale - Optional locale string (e.g., 'en-US', 'zh-CN')
|
||||
* @returns Formatted date string
|
||||
*
|
||||
* @example
|
||||
* formatUnixTimestamp(1735555200) // "Dec 30, 2024"
|
||||
* formatUnixTimestamp(1735555200, "zh-CN") // "12月30日, 2024年"
|
||||
*/
|
||||
export function formatUnixTimestamp(timestamp: number): string {
|
||||
export function formatUnixTimestamp(timestamp: number, locale?: string): string {
|
||||
const date = new Date(timestamp * 1000);
|
||||
const now = new Date();
|
||||
const effectiveLocale = locale || navigator.language || 'en-US';
|
||||
const isZhCN = effectiveLocale.startsWith('zh');
|
||||
|
||||
// If it's today, show time
|
||||
if (isToday(date)) {
|
||||
return formatTime(date);
|
||||
return formatTime(date, effectiveLocale);
|
||||
}
|
||||
|
||||
// If it's yesterday
|
||||
if (isYesterday(date)) {
|
||||
return `Yesterday, ${formatTime(date)}`;
|
||||
const yesterdayLabel = isZhCN ? '昨天' : 'Yesterday';
|
||||
return `${yesterdayLabel}, ${formatTime(date, effectiveLocale)}`;
|
||||
}
|
||||
|
||||
// If it's within the last week, show day of week
|
||||
if (isWithinWeek(date)) {
|
||||
return `${getDayName(date)}, ${formatTime(date)}`;
|
||||
return `${getDayName(date, effectiveLocale)}, ${formatTime(date, effectiveLocale)}`;
|
||||
}
|
||||
|
||||
// If it's this year, don't show year
|
||||
if (date.getFullYear() === now.getFullYear()) {
|
||||
return date.toLocaleDateString('en-US', {
|
||||
return date.toLocaleDateString(effectiveLocale, {
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
});
|
||||
}
|
||||
|
||||
// Otherwise show full date
|
||||
return date.toLocaleDateString('en-US', {
|
||||
return date.toLocaleDateString(effectiveLocale, {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
year: 'numeric'
|
||||
@@ -44,14 +49,17 @@ export function formatUnixTimestamp(timestamp: number): string {
|
||||
/**
|
||||
* Formats an ISO timestamp string to a human-readable date
|
||||
* @param isoString - ISO timestamp string
|
||||
* @param locale - Optional locale string (e.g., 'en-US', 'zh-CN')
|
||||
* @returns Formatted date string
|
||||
*
|
||||
* @example
|
||||
* formatISOTimestamp("2025-01-04T10:13:29.000Z") // "Jan 4, 2025"
|
||||
* formatISOTimestamp("2025-01-04T10:13:29.000Z", "zh-CN") // "1月4日, 2025"
|
||||
*/
|
||||
export function formatISOTimestamp(isoString: string): string {
|
||||
export function formatISOTimestamp(isoString: string, locale?: string): string {
|
||||
const date = new Date(isoString);
|
||||
return formatUnixTimestamp(Math.floor(date.getTime() / 1000));
|
||||
const effectiveLocale = locale || navigator.language || 'en-US';
|
||||
return formatUnixTimestamp(Math.floor(date.getTime() / 1000), effectiveLocale);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,11 +84,14 @@ export function getFirstLine(text: string): string {
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
function formatTime(date: Date): string {
|
||||
return date.toLocaleTimeString('en-US', {
|
||||
function formatTime(date: Date, locale?: string): string {
|
||||
const effectiveLocale = locale || navigator.language || 'en-US';
|
||||
const isZhCN = effectiveLocale.startsWith('zh');
|
||||
|
||||
return date.toLocaleTimeString(effectiveLocale, {
|
||||
hour: 'numeric',
|
||||
minute: '2-digit',
|
||||
hour12: true
|
||||
hour12: !isZhCN // Chinese typically uses 24-hour format
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,22 +112,26 @@ function isWithinWeek(date: Date): boolean {
|
||||
return date > weekAgo;
|
||||
}
|
||||
|
||||
function getDayName(date: Date): string {
|
||||
return date.toLocaleDateString('en-US', { weekday: 'long' });
|
||||
function getDayName(date: Date, locale?: string): string {
|
||||
const effectiveLocale = locale || navigator.language || 'en-US';
|
||||
return date.toLocaleDateString(effectiveLocale, { weekday: 'long' });
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a timestamp to a relative time string (e.g., "2 hours ago", "3 days ago")
|
||||
* @param timestamp - Unix timestamp in milliseconds
|
||||
* @param locale - Optional locale string (e.g., 'en-US', 'zh-CN')
|
||||
* @returns Relative time string
|
||||
*
|
||||
* @example
|
||||
* formatTimeAgo(Date.now() - 3600000) // "1 hour ago"
|
||||
* formatTimeAgo(Date.now() - 86400000) // "1 day ago"
|
||||
* formatTimeAgo(Date.now() - 86400000, "zh-CN") // "1小时前"
|
||||
*/
|
||||
export function formatTimeAgo(timestamp: number): string {
|
||||
export function formatTimeAgo(timestamp: number, locale?: string): string {
|
||||
const now = Date.now();
|
||||
const diff = now - timestamp;
|
||||
const effectiveLocale = locale || navigator.language || 'en-US';
|
||||
const isZhCN = effectiveLocale.startsWith('zh');
|
||||
|
||||
const seconds = Math.floor(diff / 1000);
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
@@ -126,27 +141,51 @@ export function formatTimeAgo(timestamp: number): string {
|
||||
const months = Math.floor(days / 30);
|
||||
const years = Math.floor(days / 365);
|
||||
|
||||
if (years > 0) {
|
||||
return years === 1 ? '1 year ago' : `${years} years ago`;
|
||||
if (isZhCN) {
|
||||
if (years > 0) {
|
||||
return `${years}年前`;
|
||||
}
|
||||
if (months > 0) {
|
||||
return `${months}个月前`;
|
||||
}
|
||||
if (weeks > 0) {
|
||||
return `${weeks}周前`;
|
||||
}
|
||||
if (days > 0) {
|
||||
return `${days}天前`;
|
||||
}
|
||||
if (hours > 0) {
|
||||
return `${hours}小时前`;
|
||||
}
|
||||
if (minutes > 0) {
|
||||
return `${minutes}分钟前`;
|
||||
}
|
||||
if (seconds > 0) {
|
||||
return `${seconds}秒前`;
|
||||
}
|
||||
return '刚刚';
|
||||
} else {
|
||||
if (years > 0) {
|
||||
return years === 1 ? '1 year ago' : `${years} years ago`;
|
||||
}
|
||||
if (months > 0) {
|
||||
return months === 1 ? '1 month ago' : `${months} months ago`;
|
||||
}
|
||||
if (weeks > 0) {
|
||||
return weeks === 1 ? '1 week ago' : `${weeks} weeks ago`;
|
||||
}
|
||||
if (days > 0) {
|
||||
return days === 1 ? '1 day ago' : `${days} days ago`;
|
||||
}
|
||||
if (hours > 0) {
|
||||
return hours === 1 ? '1 hour ago' : `${hours} hours ago`;
|
||||
}
|
||||
if (minutes > 0) {
|
||||
return minutes === 1 ? '1 minute ago' : `${minutes} minutes ago`;
|
||||
}
|
||||
if (seconds > 0) {
|
||||
return seconds === 1 ? '1 second ago' : `${seconds} seconds ago`;
|
||||
}
|
||||
return 'just now';
|
||||
}
|
||||
if (months > 0) {
|
||||
return months === 1 ? '1 month ago' : `${months} months ago`;
|
||||
}
|
||||
if (weeks > 0) {
|
||||
return weeks === 1 ? '1 week ago' : `${weeks} weeks ago`;
|
||||
}
|
||||
if (days > 0) {
|
||||
return days === 1 ? '1 day ago' : `${days} days ago`;
|
||||
}
|
||||
if (hours > 0) {
|
||||
return hours === 1 ? '1 hour ago' : `${hours} hours ago`;
|
||||
}
|
||||
if (minutes > 0) {
|
||||
return minutes === 1 ? '1 minute ago' : `${minutes} minutes ago`;
|
||||
}
|
||||
if (seconds > 0) {
|
||||
return seconds === 1 ? '1 second ago' : `${seconds} seconds ago`;
|
||||
}
|
||||
|
||||
return 'just now';
|
||||
}
|
||||
|
Reference in New Issue
Block a user