กำหนดDateTime
ค่าเฉพาะฉันจะแสดงเวลาที่สัมพันธ์กันได้อย่างไรเช่น:
- 1 ชั่วโมงที่แล้ว
- 3 วันที่แล้ว
- เดือนที่แล้ว
กำหนดDateTime
ค่าเฉพาะฉันจะแสดงเวลาที่สัมพันธ์กันได้อย่างไรเช่น:
คำตอบ:
Jeff รหัสของคุณดี แต่อาจชัดเจนกับค่าคงที่ (ตามที่แนะนำใน Code Complete)
const int SECOND = 1;
const int MINUTE = 60 * SECOND;
const int HOUR = 60 * MINUTE;
const int DAY = 24 * HOUR;
const int MONTH = 30 * DAY;
var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);
double delta = Math.Abs(ts.TotalSeconds);
if (delta < 1 * MINUTE)
return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
if (delta < 2 * MINUTE)
return "a minute ago";
if (delta < 45 * MINUTE)
return ts.Minutes + " minutes ago";
if (delta < 90 * MINUTE)
return "an hour ago";
if (delta < 24 * HOUR)
return ts.Hours + " hours ago";
if (delta < 48 * HOUR)
return "yesterday";
if (delta < 30 * DAY)
return ts.Days + " days ago";
if (delta < 12 * MONTH)
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return months <= 1 ? "one month ago" : months + " months ago";
}
else
{
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return years <= 1 ? "one year ago" : years + " years ago";
}
Thread.Sleep(1 * MINUTE)
? เพราะมันผิดด้วย 1,000 ตัว
const int SECOND = 1;
หนึ่งวินาทีก็แปลก ๆ
เจฟฟ์เพราะกองมากเกินใช้ jQuery อย่างกว้างขวางผมขอแนะนำให้ปลั๊กอิน jquery.timeago
ประโยชน์ที่ได้รับ:
เพียงแนบไปกับการประทับเวลาของคุณบน DOM พร้อม:
jQuery(document).ready(function() {
jQuery('abbr.timeago').timeago();
});
สิ่งนี้จะเปลี่ยนabbr
องค์ประกอบทั้งหมดด้วยคลาสของ timeago และเวลามาตรฐาน ISO 8601ในชื่อเรื่อง:
<abbr class="timeago" title="2008-07-17T09:24:17Z">July 17, 2008</abbr>
เป็นอะไรเช่นนี้:
<abbr class="timeago" title="July 17, 2008">4 months ago</abbr>
ซึ่งให้ผล: 4 เดือนที่แล้ว เมื่อเวลาผ่านไปการประทับเวลาจะอัปเดตโดยอัตโนมัติ
คำเตือน: ฉันเขียนปลั๊กอินนี้ดังนั้นฉันจึงมีอคติ
นี่คือวิธีที่ฉันทำ
var ts = new TimeSpan(DateTime.UtcNow.Ticks - dt.Ticks);
double delta = Math.Abs(ts.TotalSeconds);
if (delta < 60)
{
return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
}
if (delta < 120)
{
return "a minute ago";
}
if (delta < 2700) // 45 * 60
{
return ts.Minutes + " minutes ago";
}
if (delta < 5400) // 90 * 60
{
return "an hour ago";
}
if (delta < 86400) // 24 * 60 * 60
{
return ts.Hours + " hours ago";
}
if (delta < 172800) // 48 * 60 * 60
{
return "yesterday";
}
if (delta < 2592000) // 30 * 24 * 60 * 60
{
return ts.Days + " days ago";
}
if (delta < 31104000) // 12 * 30 * 24 * 60 * 60
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return months <= 1 ? "one month ago" : months + " months ago";
}
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return years <= 1 ? "one year ago" : years + " years ago";
ข้อเสนอแนะ? ความคิดเห็น? วิธีในการปรับปรุงอัลกอริทึมนี้
public static string RelativeDate(DateTime theDate)
{
Dictionary<long, string> thresholds = new Dictionary<long, string>();
int minute = 60;
int hour = 60 * minute;
int day = 24 * hour;
thresholds.Add(60, "{0} seconds ago");
thresholds.Add(minute * 2, "a minute ago");
thresholds.Add(45 * minute, "{0} minutes ago");
thresholds.Add(120 * minute, "an hour ago");
thresholds.Add(day, "{0} hours ago");
thresholds.Add(day * 2, "yesterday");
thresholds.Add(day * 30, "{0} days ago");
thresholds.Add(day * 365, "{0} months ago");
thresholds.Add(long.MaxValue, "{0} years ago");
long since = (DateTime.Now.Ticks - theDate.Ticks) / 10000000;
foreach (long threshold in thresholds.Keys)
{
if (since < threshold)
{
TimeSpan t = new TimeSpan((DateTime.Now.Ticks - theDate.Ticks));
return string.Format(thresholds[threshold], (t.Days > 365 ? t.Days / 365 : (t.Days > 0 ? t.Days : (t.Hours > 0 ? t.Hours : (t.Minutes > 0 ? t.Minutes : (t.Seconds > 0 ? t.Seconds : 0))))).ToString());
}
}
return "";
}
ฉันชอบเวอร์ชั่นนี้สำหรับความกระชับและความสามารถในการเพิ่มคะแนนติ๊กใหม่ สิ่งนี้สามารถห่อหุ้มด้วยLatest()
ส่วนขยายไปยังไทม์แปนแทนที่จะเป็น 1 ไลเนอร์ที่ยาว แต่เพื่อความสะดวกในการโพสต์สิ่งนี้จะทำ
วิธีนี้จะแก้ไขชั่วโมงที่ผ่านมา 1 ชั่วโมงที่ผ่านมาโดยให้ผ่านไปหนึ่งชั่วโมงจนถึง 2 ชั่วโมงที่ผ่านไป
SortedDictionary
แทนแบบธรรมดาDictionary
: การใช้งานเหมือนกัน แต่ช่วยให้มั่นใจได้ว่าจะมีการเรียงลำดับคีย์ แต่ถึงกระนั้นอัลกอริทึมก็มีข้อบกพร่องเพราะRelativeDate(DateTime.Now.AddMonths(-3).AddDays(-3))
ส่งคืน"95 เดือนที่ผ่านมา"ไม่ว่าคุณจะใช้พจนานุกรมประเภทใดซึ่งไม่ถูกต้อง (ควรคืน "3 เดือนก่อน" หรือ "4 เดือนก่อน" ขึ้นอยู่กับเกณฑ์ของคุณ) กำลังใช้งานอยู่) - แม้ว่า -3 จะไม่สร้างวันที่ในปีที่ผ่านมา (ฉันได้ทดสอบสิ่งนี้ในเดือนธันวาคมดังนั้นในกรณีนี้มันไม่ควรเกิดขึ้น)
นี่คือการเขียนซ้ำจาก Jeffs Script สำหรับ PHP:
define("SECOND", 1);
define("MINUTE", 60 * SECOND);
define("HOUR", 60 * MINUTE);
define("DAY", 24 * HOUR);
define("MONTH", 30 * DAY);
function relativeTime($time)
{
$delta = time() - $time;
if ($delta < 1 * MINUTE)
{
return $delta == 1 ? "one second ago" : $delta . " seconds ago";
}
if ($delta < 2 * MINUTE)
{
return "a minute ago";
}
if ($delta < 45 * MINUTE)
{
return floor($delta / MINUTE) . " minutes ago";
}
if ($delta < 90 * MINUTE)
{
return "an hour ago";
}
if ($delta < 24 * HOUR)
{
return floor($delta / HOUR) . " hours ago";
}
if ($delta < 48 * HOUR)
{
return "yesterday";
}
if ($delta < 30 * DAY)
{
return floor($delta / DAY) . " days ago";
}
if ($delta < 12 * MONTH)
{
$months = floor($delta / DAY / 30);
return $months <= 1 ? "one month ago" : $months . " months ago";
}
else
{
$years = floor($delta / DAY / 365);
return $years <= 1 ? "one year ago" : $years . " years ago";
}
}
public static string ToRelativeDate(DateTime input)
{
TimeSpan oSpan = DateTime.Now.Subtract(input);
double TotalMinutes = oSpan.TotalMinutes;
string Suffix = " ago";
if (TotalMinutes < 0.0)
{
TotalMinutes = Math.Abs(TotalMinutes);
Suffix = " from now";
}
var aValue = new SortedList<double, Func<string>>();
aValue.Add(0.75, () => "less than a minute");
aValue.Add(1.5, () => "about a minute");
aValue.Add(45, () => string.Format("{0} minutes", Math.Round(TotalMinutes)));
aValue.Add(90, () => "about an hour");
aValue.Add(1440, () => string.Format("about {0} hours", Math.Round(Math.Abs(oSpan.TotalHours)))); // 60 * 24
aValue.Add(2880, () => "a day"); // 60 * 48
aValue.Add(43200, () => string.Format("{0} days", Math.Floor(Math.Abs(oSpan.TotalDays)))); // 60 * 24 * 30
aValue.Add(86400, () => "about a month"); // 60 * 24 * 60
aValue.Add(525600, () => string.Format("{0} months", Math.Floor(Math.Abs(oSpan.TotalDays / 30)))); // 60 * 24 * 365
aValue.Add(1051200, () => "about a year"); // 60 * 24 * 365 * 2
aValue.Add(double.MaxValue, () => string.Format("{0} years", Math.Floor(Math.Abs(oSpan.TotalDays / 365))));
return aValue.First(n => TotalMinutes < n.Key).Value.Invoke() + Suffix;
}
http://refactormycode.com/codes/493-twitter-esque-relative-dates
รุ่น C # 6:
static readonly SortedList<double, Func<TimeSpan, string>> offsets =
new SortedList<double, Func<TimeSpan, string>>
{
{ 0.75, _ => "less than a minute"},
{ 1.5, _ => "about a minute"},
{ 45, x => $"{x.TotalMinutes:F0} minutes"},
{ 90, x => "about an hour"},
{ 1440, x => $"about {x.TotalHours:F0} hours"},
{ 2880, x => "a day"},
{ 43200, x => $"{x.TotalDays:F0} days"},
{ 86400, x => "about a month"},
{ 525600, x => $"{x.TotalDays / 30:F0} months"},
{ 1051200, x => "about a year"},
{ double.MaxValue, x => $"{x.TotalDays / 365:F0} years"}
};
public static string ToRelativeDate(this DateTime input)
{
TimeSpan x = DateTime.Now - input;
string Suffix = x.TotalMinutes > 0 ? " ago" : " from now";
x = new TimeSpan(Math.Abs(x.Ticks));
return offsets.First(n => x.TotalMinutes < n.Key).Value(x) + Suffix;
}
Func<string>
Func<double>
ต่อไปนี้เป็นการนำไปใช้ที่ฉันเพิ่มเป็นวิธีการขยายไปยังคลาส DateTime ที่จัดการทั้งวันที่ในอนาคตและวันที่ผ่านมาและมีตัวเลือกการประมาณที่ช่วยให้คุณระบุระดับรายละเอียดที่คุณกำลังมองหา ("3 ชั่วโมงก่อน" vs "3 ชั่วโมง" 23 นาที, 12 วินาทีก่อน "):
using System.Text;
/// <summary>
/// Compares a supplied date to the current date and generates a friendly English
/// comparison ("5 days ago", "5 days from now")
/// </summary>
/// <param name="date">The date to convert</param>
/// <param name="approximate">When off, calculate timespan down to the second.
/// When on, approximate to the largest round unit of time.</param>
/// <returns></returns>
public static string ToRelativeDateString(this DateTime value, bool approximate)
{
StringBuilder sb = new StringBuilder();
string suffix = (value > DateTime.Now) ? " from now" : " ago";
TimeSpan timeSpan = new TimeSpan(Math.Abs(DateTime.Now.Subtract(value).Ticks));
if (timeSpan.Days > 0)
{
sb.AppendFormat("{0} {1}", timeSpan.Days,
(timeSpan.Days > 1) ? "days" : "day");
if (approximate) return sb.ToString() + suffix;
}
if (timeSpan.Hours > 0)
{
sb.AppendFormat("{0}{1} {2}", (sb.Length > 0) ? ", " : string.Empty,
timeSpan.Hours, (timeSpan.Hours > 1) ? "hours" : "hour");
if (approximate) return sb.ToString() + suffix;
}
if (timeSpan.Minutes > 0)
{
sb.AppendFormat("{0}{1} {2}", (sb.Length > 0) ? ", " : string.Empty,
timeSpan.Minutes, (timeSpan.Minutes > 1) ? "minutes" : "minute");
if (approximate) return sb.ToString() + suffix;
}
if (timeSpan.Seconds > 0)
{
sb.AppendFormat("{0}{1} {2}", (sb.Length > 0) ? ", " : string.Empty,
timeSpan.Seconds, (timeSpan.Seconds > 1) ? "seconds" : "second");
if (approximate) return sb.ToString() + suffix;
}
if (sb.Length == 0) return "right now";
sb.Append(suffix);
return sb.ToString();
}
ฉันขอแนะนำให้คำนวณสิ่งนี้ในฝั่งไคลเอ็นต์ด้วย ทำงานน้อยลงสำหรับเซิร์ฟเวอร์
ต่อไปนี้เป็นรุ่นที่ฉันใช้ (จาก Zach Leatherman)
/*
* Javascript Humane Dates
* Copyright (c) 2008 Dean Landolt (deanlandolt.com)
* Re-write by Zach Leatherman (zachleat.com)
*
* Adopted from the John Resig's pretty.js
* at http://ejohn.org/blog/javascript-pretty-date
* and henrah's proposed modification
* at http://ejohn.org/blog/javascript-pretty-date/#comment-297458
*
* Licensed under the MIT license.
*/
function humane_date(date_str){
var time_formats = [
[60, 'just now'],
[90, '1 minute'], // 60*1.5
[3600, 'minutes', 60], // 60*60, 60
[5400, '1 hour'], // 60*60*1.5
[86400, 'hours', 3600], // 60*60*24, 60*60
[129600, '1 day'], // 60*60*24*1.5
[604800, 'days', 86400], // 60*60*24*7, 60*60*24
[907200, '1 week'], // 60*60*24*7*1.5
[2628000, 'weeks', 604800], // 60*60*24*(365/12), 60*60*24*7
[3942000, '1 month'], // 60*60*24*(365/12)*1.5
[31536000, 'months', 2628000], // 60*60*24*365, 60*60*24*(365/12)
[47304000, '1 year'], // 60*60*24*365*1.5
[3153600000, 'years', 31536000], // 60*60*24*365*100, 60*60*24*365
[4730400000, '1 century'] // 60*60*24*365*100*1.5
];
var time = ('' + date_str).replace(/-/g,"/").replace(/[TZ]/g," "),
dt = new Date,
seconds = ((dt - new Date(time) + (dt.getTimezoneOffset() * 60000)) / 1000),
token = ' ago',
i = 0,
format;
if (seconds < 0) {
seconds = Math.abs(seconds);
token = '';
}
while (format = time_formats[i++]) {
if (seconds < format[0]) {
if (format.length == 2) {
return format[1] + (i > 1 ? token : ''); // Conditional so we don't return Just Now Ago
} else {
return Math.round(seconds / format[2]) + ' ' + format[1] + (i > 1 ? token : '');
}
}
}
// overflow for centuries
if(seconds > 4730400000)
return Math.round(seconds / 4730400000) + ' centuries' + token;
return date_str;
};
if(typeof jQuery != 'undefined') {
jQuery.fn.humane_dates = function(){
return this.each(function(){
var date = humane_date(this.title);
if(date && jQuery(this).text() != date) // don't modify the dom if we don't have to
jQuery(this).text(date);
});
};
}
นอกจากนี้ยังมีแพ็คเกจที่เรียกว่าHumanizrบน Nuget และใช้งานได้ดีจริง ๆ และอยู่ใน. NET Foundation
DateTime.UtcNow.AddHours(-30).Humanize() => "yesterday"
DateTime.UtcNow.AddHours(-2).Humanize() => "2 hours ago"
DateTime.UtcNow.AddHours(30).Humanize() => "tomorrow"
DateTime.UtcNow.AddHours(2).Humanize() => "2 hours from now"
TimeSpan.FromMilliseconds(1299630020).Humanize() => "2 weeks"
TimeSpan.FromMilliseconds(1299630020).Humanize(3) => "2 weeks, 1 day, 1 hour"
Scott Hanselman มีบทความบนบล็อกของเขา
@ Jeff
IMHO ของคุณดูเหมือนจะยาวไปหน่อย อย่างไรก็ตามดูเหมือนจะแข็งแกร่งขึ้นเล็กน้อยด้วยการรองรับ "เมื่อวาน" และ "ปี" แต่จากประสบการณ์ของฉันเมื่อมีการใช้งานบุคคลนั้นมักจะดูเนื้อหาใน 30 วันแรก มันเป็นเพียงคนไม่ยอมใครง่ายๆจริงๆที่มาหลังจากนั้น นั่นคือเหตุผลที่ฉันมักจะเลือกที่จะรักษาให้สั้นและเรียบง่าย
นี่เป็นวิธีที่ฉันใช้ในเว็บไซต์ของฉัน สิ่งนี้จะส่งคืนวันชั่วโมงเวลาที่สัมพัทธ์เท่านั้น และจากนั้นผู้ใช้จะต้องตบที่ "ที่ผ่านมา" ในการส่งออก
public static string ToLongString(this TimeSpan time)
{
string output = String.Empty;
if (time.Days > 0)
output += time.Days + " days ";
if ((time.Days == 0 || time.Days == 1) && time.Hours > 0)
output += time.Hours + " hr ";
if (time.Days == 0 && time.Minutes > 0)
output += time.Minutes + " min ";
if (output.Length == 0)
output += time.Seconds + " sec";
return output.Trim();
}
สองสามปีที่ผ่านมาถึงงานปาร์ตี้ แต่ฉันมีความต้องการที่จะทำสิ่งนี้ทั้งในอดีตและในอนาคตดังนั้นฉันจึงรวมเจฟกับวินเซนต์เข้าด้วยกัน มันเป็นมหกรรมนอกสถานที่! :)
public static class DateTimeHelper
{
private const int SECOND = 1;
private const int MINUTE = 60 * SECOND;
private const int HOUR = 60 * MINUTE;
private const int DAY = 24 * HOUR;
private const int MONTH = 30 * DAY;
/// <summary>
/// Returns a friendly version of the provided DateTime, relative to now. E.g.: "2 days ago", or "in 6 months".
/// </summary>
/// <param name="dateTime">The DateTime to compare to Now</param>
/// <returns>A friendly string</returns>
public static string GetFriendlyRelativeTime(DateTime dateTime)
{
if (DateTime.UtcNow.Ticks == dateTime.Ticks)
{
return "Right now!";
}
bool isFuture = (DateTime.UtcNow.Ticks < dateTime.Ticks);
var ts = DateTime.UtcNow.Ticks < dateTime.Ticks ? new TimeSpan(dateTime.Ticks - DateTime.UtcNow.Ticks) : new TimeSpan(DateTime.UtcNow.Ticks - dateTime.Ticks);
double delta = ts.TotalSeconds;
if (delta < 1 * MINUTE)
{
return isFuture ? "in " + (ts.Seconds == 1 ? "one second" : ts.Seconds + " seconds") : ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
}
if (delta < 2 * MINUTE)
{
return isFuture ? "in a minute" : "a minute ago";
}
if (delta < 45 * MINUTE)
{
return isFuture ? "in " + ts.Minutes + " minutes" : ts.Minutes + " minutes ago";
}
if (delta < 90 * MINUTE)
{
return isFuture ? "in an hour" : "an hour ago";
}
if (delta < 24 * HOUR)
{
return isFuture ? "in " + ts.Hours + " hours" : ts.Hours + " hours ago";
}
if (delta < 48 * HOUR)
{
return isFuture ? "tomorrow" : "yesterday";
}
if (delta < 30 * DAY)
{
return isFuture ? "in " + ts.Days + " days" : ts.Days + " days ago";
}
if (delta < 12 * MONTH)
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return isFuture ? "in " + (months <= 1 ? "one month" : months + " months") : months <= 1 ? "one month ago" : months + " months ago";
}
else
{
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return isFuture ? "in " + (years <= 1 ? "one year" : years + " years") : years <= 1 ? "one year ago" : years + " years ago";
}
}
}
มีวิธีง่าย ๆ ใน Java หรือไม่ java.util.Date
ระดับดูเหมือนว่าค่อนข้าง จำกัด
นี่คือโซลูชัน Java ที่รวดเร็วและสกปรกของฉัน:
import java.util.Date;
import javax.management.timer.Timer;
String getRelativeDate(Date date) {
long delta = new Date().getTime() - date.getTime();
if (delta < 1L * Timer.ONE_MINUTE) {
return toSeconds(delta) == 1 ? "one second ago" : toSeconds(delta) + " seconds ago";
}
if (delta < 2L * Timer.ONE_MINUTE) {
return "a minute ago";
}
if (delta < 45L * Timer.ONE_MINUTE) {
return toMinutes(delta) + " minutes ago";
}
if (delta < 90L * Timer.ONE_MINUTE) {
return "an hour ago";
}
if (delta < 24L * Timer.ONE_HOUR) {
return toHours(delta) + " hours ago";
}
if (delta < 48L * Timer.ONE_HOUR) {
return "yesterday";
}
if (delta < 30L * Timer.ONE_DAY) {
return toDays(delta) + " days ago";
}
if (delta < 12L * 4L * Timer.ONE_WEEK) { // a month
long months = toMonths(delta);
return months <= 1 ? "one month ago" : months + " months ago";
}
else {
long years = toYears(delta);
return years <= 1 ? "one year ago" : years + " years ago";
}
}
private long toSeconds(long date) {
return date / 1000L;
}
private long toMinutes(long date) {
return toSeconds(date) / 60L;
}
private long toHours(long date) {
return toMinutes(date) / 60L;
}
private long toDays(long date) {
return toHours(date) / 24L;
}
private long toMonths(long date) {
return toDays(date) / 30L;
}
private long toYears(long date) {
return toMonths(date) / 365L;
}
+ (NSString *)timeAgoString:(NSDate *)date {
int delta = -(int)[date timeIntervalSinceNow];
if (delta < 60)
{
return delta == 1 ? @"one second ago" : [NSString stringWithFormat:@"%i seconds ago", delta];
}
if (delta < 120)
{
return @"a minute ago";
}
if (delta < 2700)
{
return [NSString stringWithFormat:@"%i minutes ago", delta/60];
}
if (delta < 5400)
{
return @"an hour ago";
}
if (delta < 24 * 3600)
{
return [NSString stringWithFormat:@"%i hours ago", delta/3600];
}
if (delta < 48 * 3600)
{
return @"yesterday";
}
if (delta < 30 * 24 * 3600)
{
return [NSString stringWithFormat:@"%i days ago", delta/(24*3600)];
}
if (delta < 12 * 30 * 24 * 3600)
{
int months = delta/(30*24*3600);
return months <= 1 ? @"one month ago" : [NSString stringWithFormat:@"%i months ago", months];
}
else
{
int years = delta/(12*30*24*3600);
return years <= 1 ? @"one year ago" : [NSString stringWithFormat:@"%i years ago", years];
}
}
ให้โลกและสามีของเธอดูเหมือนจะโพสต์ตัวอย่างโค้ดนี่คือสิ่งที่ฉันเขียนเมื่อไม่นานมานี้ตามคำตอบเหล่านี้สองสามข้อ
ฉันมีความต้องการเฉพาะสำหรับรหัสนี้เพื่อให้สามารถแปลได้ ดังนั้นฉันจึงมีสองคลาส - Grammar
ซึ่งระบุคำศัพท์ที่สามารถแปลได้และFuzzyDateExtensions
ซึ่งมีวิธีการขยายจำนวนมาก ฉันไม่จำเป็นต้องจัดการกับชุดข้อมูลในอนาคตดังนั้นจึงไม่มีความพยายามในการจัดการกับรหัสนี้
ฉันได้ทิ้งบางส่วนของ XMLdoc ไว้ในแหล่งข้อมูล แต่ลบส่วนใหญ่ (ซึ่งเป็นที่ชัดเจน) เพื่อประโยชน์ของความกะทัดรัด ฉันยังไม่รวมสมาชิกชั้นเรียนทุกคนที่นี่:
public class Grammar
{
/// <summary> Gets or sets the term for "just now". </summary>
public string JustNow { get; set; }
/// <summary> Gets or sets the term for "X minutes ago". </summary>
/// <remarks>
/// This is a <see cref="String.Format"/> pattern, where <c>{0}</c>
/// is the number of minutes.
/// </remarks>
public string MinutesAgo { get; set; }
public string OneHourAgo { get; set; }
public string HoursAgo { get; set; }
public string Yesterday { get; set; }
public string DaysAgo { get; set; }
public string LastMonth { get; set; }
public string MonthsAgo { get; set; }
public string LastYear { get; set; }
public string YearsAgo { get; set; }
/// <summary> Gets or sets the term for "ages ago". </summary>
public string AgesAgo { get; set; }
/// <summary>
/// Gets or sets the threshold beyond which the fuzzy date should be
/// considered "ages ago".
/// </summary>
public TimeSpan AgesAgoThreshold { get; set; }
/// <summary>
/// Initialises a new <see cref="Grammar"/> instance with the
/// specified properties.
/// </summary>
private void Initialise(string justNow, string minutesAgo,
string oneHourAgo, string hoursAgo, string yesterday, string daysAgo,
string lastMonth, string monthsAgo, string lastYear, string yearsAgo,
string agesAgo, TimeSpan agesAgoThreshold)
{ ... }
}
FuzzyDateString
ระดับประกอบด้วย:
public static class FuzzyDateExtensions
{
public static string ToFuzzyDateString(this TimeSpan timespan)
{
return timespan.ToFuzzyDateString(new Grammar());
}
public static string ToFuzzyDateString(this TimeSpan timespan,
Grammar grammar)
{
return GetFuzzyDateString(timespan, grammar);
}
public static string ToFuzzyDateString(this DateTime datetime)
{
return (DateTime.Now - datetime).ToFuzzyDateString();
}
public static string ToFuzzyDateString(this DateTime datetime,
Grammar grammar)
{
return (DateTime.Now - datetime).ToFuzzyDateString(grammar);
}
private static string GetFuzzyDateString(TimeSpan timespan,
Grammar grammar)
{
timespan = timespan.Duration();
if (timespan >= grammar.AgesAgoThreshold)
{
return grammar.AgesAgo;
}
if (timespan < new TimeSpan(0, 2, 0)) // 2 minutes
{
return grammar.JustNow;
}
if (timespan < new TimeSpan(1, 0, 0)) // 1 hour
{
return String.Format(grammar.MinutesAgo, timespan.Minutes);
}
if (timespan < new TimeSpan(1, 55, 0)) // 1 hour 55 minutes
{
return grammar.OneHourAgo;
}
if (timespan < new TimeSpan(12, 0, 0) // 12 hours
&& (DateTime.Now - timespan).IsToday())
{
return String.Format(grammar.HoursAgo, timespan.RoundedHours());
}
if ((DateTime.Now.AddDays(1) - timespan).IsToday())
{
return grammar.Yesterday;
}
if (timespan < new TimeSpan(32, 0, 0, 0) // 32 days
&& (DateTime.Now - timespan).IsThisMonth())
{
return String.Format(grammar.DaysAgo, timespan.RoundedDays());
}
if ((DateTime.Now.AddMonths(1) - timespan).IsThisMonth())
{
return grammar.LastMonth;
}
if (timespan < new TimeSpan(365, 0, 0, 0, 0) // 365 days
&& (DateTime.Now - timespan).IsThisYear())
{
return String.Format(grammar.MonthsAgo, timespan.RoundedMonths());
}
if ((DateTime.Now - timespan).AddYears(1).IsThisYear())
{
return grammar.LastYear;
}
return String.Format(grammar.YearsAgo, timespan.RoundedYears());
}
}
หนึ่งในสิ่งสำคัญที่ผมอยากจะประสบความสำเร็จเช่นเดียวกับการแปลได้ว่า "วันนี้" เท่านั้นที่จะหมายถึง "วันปฏิทินนี้" ดังนั้นIsToday
, IsThisMonth
, IsThisYear
วิธีการลักษณะเช่นนี้
public static bool IsToday(this DateTime date)
{
return date.DayOfYear == DateTime.Now.DayOfYear && date.IsThisYear();
}
และวิธีการปัดเศษเป็นเช่นนี้ (ฉันได้รวมไว้RoundedMonths
เพราะมันแตกต่างกันเล็กน้อย):
public static int RoundedDays(this TimeSpan timespan)
{
return (timespan.Hours > 12) ? timespan.Days + 1 : timespan.Days;
}
public static int RoundedMonths(this TimeSpan timespan)
{
DateTime then = DateTime.Now - timespan;
// Number of partial months elapsed since 1 Jan, AD 1 (DateTime.MinValue)
int nowMonthYears = DateTime.Now.Year * 12 + DateTime.Now.Month;
int thenMonthYears = then.Year * 12 + then.Month;
return nowMonthYears - thenMonthYears;
}
ฉันหวังว่าผู้คนจะพบว่าสิ่งนี้มีประโยชน์และ / หรือน่าสนใจ: o)
ใน PHP ฉันทำแบบนี้:
<?php
function timesince($original) {
// array of time period chunks
$chunks = array(
array(60 * 60 * 24 * 365 , 'year'),
array(60 * 60 * 24 * 30 , 'month'),
array(60 * 60 * 24 * 7, 'week'),
array(60 * 60 * 24 , 'day'),
array(60 * 60 , 'hour'),
array(60 , 'minute'),
);
$today = time(); /* Current unix time */
$since = $today - $original;
if($since > 604800) {
$print = date("M jS", $original);
if($since > 31536000) {
$print .= ", " . date("Y", $original);
}
return $print;
}
// $j saves performing the count function each time around the loop
for ($i = 0, $j = count($chunks); $i < $j; $i++) {
$seconds = $chunks[$i][0];
$name = $chunks[$i][1];
// finding the biggest chunk (if the chunk fits, break)
if (($count = floor($since / $seconds)) != 0) {
break;
}
}
$print = ($count == 1) ? '1 '.$name : "$count {$name}s";
return $print . " ago";
} ?>
var dateTime1 = 2.Hours().Ago();
var dateTime2 = 3.Days().Ago();
var dateTime3 = 1.Months().Ago();
var dateTime4 = 5.Hours().FromNow();
var dateTime5 = 2.Weeks().FromNow();
var dateTime6 = 40.Seconds().FromNow();
ฉันคิดว่าฉันจะให้ช็อตนี้โดยใช้คลาสและพหุนาม ฉันมีการวนซ้ำก่อนหน้านี้ซึ่งใช้การจัดกลุ่มย่อยซึ่งจบลงด้วยการมีค่าใช้จ่ายมากเกินไป ฉันได้เปลี่ยนไปใช้โมเดลวัตถุออบเจ็กต์ตัวแทน / สาธารณะที่มีความยืดหยุ่นมากขึ้นซึ่งดีกว่ามาก รหัสของฉันมีความแม่นยำมากขึ้นเล็กน้อยฉันหวังว่าฉันจะสามารถหาวิธีที่ดีกว่าในการสร้าง "เดือนที่ผ่านมา" ซึ่งดูเหมือนจะไม่ได้รับการออกแบบมากเกินไป
ฉันคิดว่าฉันยังคงยึดติดกับน้ำตกถ้าหากแล้วของเจฟฟ์เพราะมันเป็นรหัสน้อยลงและมันง่ายขึ้น (มันแน่นอนง่ายขึ้นเพื่อให้แน่ใจว่ามันจะทำงานได้ตามที่คาดไว้)
สำหรับโค้ดด้านล่างPrintRelativeTime.GetRelativeTimeMessage (TimeSpan ที่ผ่านมา)จะส่งกลับข้อความเวลาสัมพัทธ์ (เช่น "เมื่อวาน")
public class RelativeTimeRange : IComparable
{
public TimeSpan UpperBound { get; set; }
public delegate string RelativeTimeTextDelegate(TimeSpan timeDelta);
public RelativeTimeTextDelegate MessageCreator { get; set; }
public int CompareTo(object obj)
{
if (!(obj is RelativeTimeRange))
{
return 1;
}
// note that this sorts in reverse order to the way you'd expect,
// this saves having to reverse a list later
return (obj as RelativeTimeRange).UpperBound.CompareTo(UpperBound);
}
}
public class PrintRelativeTime
{
private static List<RelativeTimeRange> timeRanges;
static PrintRelativeTime()
{
timeRanges = new List<RelativeTimeRange>{
new RelativeTimeRange
{
UpperBound = TimeSpan.FromSeconds(1),
MessageCreator = (delta) =>
{ return "one second ago"; }
},
new RelativeTimeRange
{
UpperBound = TimeSpan.FromSeconds(60),
MessageCreator = (delta) =>
{ return delta.Seconds + " seconds ago"; }
},
new RelativeTimeRange
{
UpperBound = TimeSpan.FromMinutes(2),
MessageCreator = (delta) =>
{ return "one minute ago"; }
},
new RelativeTimeRange
{
UpperBound = TimeSpan.FromMinutes(60),
MessageCreator = (delta) =>
{ return delta.Minutes + " minutes ago"; }
},
new RelativeTimeRange
{
UpperBound = TimeSpan.FromHours(2),
MessageCreator = (delta) =>
{ return "one hour ago"; }
},
new RelativeTimeRange
{
UpperBound = TimeSpan.FromHours(24),
MessageCreator = (delta) =>
{ return delta.Hours + " hours ago"; }
},
new RelativeTimeRange
{
UpperBound = TimeSpan.FromDays(2),
MessageCreator = (delta) =>
{ return "yesterday"; }
},
new RelativeTimeRange
{
UpperBound = DateTime.Now.Subtract(DateTime.Now.AddMonths(-1)),
MessageCreator = (delta) =>
{ return delta.Days + " days ago"; }
},
new RelativeTimeRange
{
UpperBound = DateTime.Now.Subtract(DateTime.Now.AddMonths(-2)),
MessageCreator = (delta) =>
{ return "one month ago"; }
},
new RelativeTimeRange
{
UpperBound = DateTime.Now.Subtract(DateTime.Now.AddYears(-1)),
MessageCreator = (delta) =>
{ return (int)Math.Floor(delta.TotalDays / 30) + " months ago"; }
},
new RelativeTimeRange
{
UpperBound = DateTime.Now.Subtract(DateTime.Now.AddYears(-2)),
MessageCreator = (delta) =>
{ return "one year ago"; }
},
new RelativeTimeRange
{
UpperBound = TimeSpan.MaxValue,
MessageCreator = (delta) =>
{ return (int)Math.Floor(delta.TotalDays / 365.24D) + " years ago"; }
}
};
timeRanges.Sort();
}
public static string GetRelativeTimeMessage(TimeSpan ago)
{
RelativeTimeRange postRelativeDateRange = timeRanges[0];
foreach (var timeRange in timeRanges)
{
if (ago.CompareTo(timeRange.UpperBound) <= 0)
{
postRelativeDateRange = timeRange;
}
}
return postRelativeDateRange.MessageCreator(ago);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
public static class RelativeDateHelper
{
private static Dictionary<double, Func<double, string>> sm_Dict = null;
private static Dictionary<double, Func<double, string>> DictionarySetup()
{
var dict = new Dictionary<double, Func<double, string>>();
dict.Add(0.75, (mins) => "less than a minute");
dict.Add(1.5, (mins) => "about a minute");
dict.Add(45, (mins) => string.Format("{0} minutes", Math.Round(mins)));
dict.Add(90, (mins) => "about an hour");
dict.Add(1440, (mins) => string.Format("about {0} hours", Math.Round(Math.Abs(mins / 60)))); // 60 * 24
dict.Add(2880, (mins) => "a day"); // 60 * 48
dict.Add(43200, (mins) => string.Format("{0} days", Math.Floor(Math.Abs(mins / 1440)))); // 60 * 24 * 30
dict.Add(86400, (mins) => "about a month"); // 60 * 24 * 60
dict.Add(525600, (mins) => string.Format("{0} months", Math.Floor(Math.Abs(mins / 43200)))); // 60 * 24 * 365
dict.Add(1051200, (mins) => "about a year"); // 60 * 24 * 365 * 2
dict.Add(double.MaxValue, (mins) => string.Format("{0} years", Math.Floor(Math.Abs(mins / 525600))));
return dict;
}
public static string ToRelativeDate(this DateTime input)
{
TimeSpan oSpan = DateTime.Now.Subtract(input);
double TotalMinutes = oSpan.TotalMinutes;
string Suffix = " ago";
if (TotalMinutes < 0.0)
{
TotalMinutes = Math.Abs(TotalMinutes);
Suffix = " from now";
}
if (null == sm_Dict)
sm_Dict = DictionarySetup();
return sm_Dict.First(n => TotalMinutes < n.Key).Value.Invoke(TotalMinutes) + Suffix;
}
}
เหมือนกับคำตอบอื่นสำหรับคำถามนี้แต่เป็นวิธีส่วนขยายที่มีพจนานุกรมแบบคงที่
Dictionary
อเมริการะบุว่า "ลำดับที่ส่งคืนไอเท็มไม่ได้ถูกกำหนด" ( msdn.microsoft.com/en-us/library/xfhwa508.aspx ) บางทีนั่นอาจไม่ใช่โครงสร้างข้อมูลที่ดีที่สุดที่จะใช้ เมื่อคุณไม่สนใจเวลาค้นหาเท่าที่มีสิ่งของอยู่ในระเบียบ
Dictionary
s หากคุณยังรู้สึกไม่สะดวกใจคุณสามารถใช้SortedDictionary
แต่ประสบการณ์ของฉันเองแสดงให้เห็นว่าไม่จำเป็น
เมื่อคุณทราบเขตเวลาของผู้ดูอาจชัดเจนกว่าที่จะใช้วันตามปฏิทินในระดับวัน ฉันไม่คุ้นเคยกับไลบรารี. NET ดังนั้นฉันจึงไม่รู้วิธีที่คุณทำใน C # แต่น่าเสียดาย
ในเว็บไซต์ของผู้บริโภคคุณอาจใช้เวลาไม่ถึงนาที "น้อยกว่าหนึ่งนาทีที่ผ่านมา" หรือ "เพิ่ง" อาจดีพอ
คุณสามารถลองสิ่งนี้ฉันคิดว่ามันจะทำงานได้อย่างถูกต้อง
long delta = new Date().getTime() - date.getTime();
const int SECOND = 1;
const int MINUTE = 60 * SECOND;
const int HOUR = 60 * MINUTE;
const int DAY = 24 * HOUR;
const int MONTH = 30 * DAY;
if (delta < 0L)
{
return "not yet";
}
if (delta < 1L * MINUTE)
{
return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
}
if (delta < 2L * MINUTE)
{
return "a minute ago";
}
if (delta < 45L * MINUTE)
{
return ts.Minutes + " minutes ago";
}
if (delta < 90L * MINUTE)
{
return "an hour ago";
}
if (delta < 24L * HOUR)
{
return ts.Hours + " hours ago";
}
if (delta < 48L * HOUR)
{
return "yesterday";
}
if (delta < 30L * DAY)
{
return ts.Days + " days ago";
}
if (delta < 12L * MONTH)
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return months <= 1 ? "one month ago" : months + " months ago";
}
else
{
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return years <= 1 ? "one year ago" : years + " years ago";
}
Java สำหรับการใช้ gwt ฝั่งไคลเอ็นต์:
import java.util.Date;
public class RelativeDateFormat {
private static final long ONE_MINUTE = 60000L;
private static final long ONE_HOUR = 3600000L;
private static final long ONE_DAY = 86400000L;
private static final long ONE_WEEK = 604800000L;
public static String format(Date date) {
long delta = new Date().getTime() - date.getTime();
if (delta < 1L * ONE_MINUTE) {
return toSeconds(delta) == 1 ? "one second ago" : toSeconds(delta)
+ " seconds ago";
}
if (delta < 2L * ONE_MINUTE) {
return "one minute ago";
}
if (delta < 45L * ONE_MINUTE) {
return toMinutes(delta) + " minutes ago";
}
if (delta < 90L * ONE_MINUTE) {
return "one hour ago";
}
if (delta < 24L * ONE_HOUR) {
return toHours(delta) + " hours ago";
}
if (delta < 48L * ONE_HOUR) {
return "yesterday";
}
if (delta < 30L * ONE_DAY) {
return toDays(delta) + " days ago";
}
if (delta < 12L * 4L * ONE_WEEK) {
long months = toMonths(delta);
return months <= 1 ? "one month ago" : months + " months ago";
} else {
long years = toYears(delta);
return years <= 1 ? "one year ago" : years + " years ago";
}
}
private static long toSeconds(long date) {
return date / 1000L;
}
private static long toMinutes(long date) {
return toSeconds(date) / 60L;
}
private static long toHours(long date) {
return toMinutes(date) / 60L;
}
private static long toDays(long date) {
return toHours(date) / 24L;
}
private static long toMonths(long date) {
return toDays(date) / 30L;
}
private static long toYears(long date) {
return toMonths(date) / 365L;
}
}
@ Jeff
var ts = new TimeSpan(DateTime.UtcNow.Ticks - dt.Ticks);
ทำการลบเมื่อDateTime
ส่งคืนค่าTimeSpan
อยู่ดี
ดังนั้นคุณสามารถทำได้
(DateTime.UtcNow - dt).TotalSeconds
ฉันยังประหลาดใจที่เห็นค่าคงที่คูณด้วยมือแล้วความคิดเห็นที่เพิ่มเข้ามาด้วยการคูณในนั่นคือการเพิ่มประสิทธิภาพที่เข้าใจผิดบางอย่างหรือไม่
นี่คืออัลกอริทึม stackoverflow ใช้ แต่เขียนใหม่รัดกุมมากขึ้นใน perse pocudocode perlish ด้วยการแก้ไขข้อบกพร่อง (ไม่ใช่ "หนึ่งชั่วโมงที่ผ่านมา") ฟังก์ชั่นนี้ใช้เวลา (บวก) จำนวนวินาทีที่แล้วและส่งกลับสตริงที่เป็นมิตรกับมนุษย์เช่น "3 ชั่วโมงก่อน" หรือ "เมื่อวาน"
agoify($delta)
local($y, $mo, $d, $h, $m, $s);
$s = floor($delta);
if($s<=1) return "a second ago";
if($s<60) return "$s seconds ago";
$m = floor($s/60);
if($m==1) return "a minute ago";
if($m<45) return "$m minutes ago";
$h = floor($m/60);
if($h==1) return "an hour ago";
if($h<24) return "$h hours ago";
$d = floor($h/24);
if($d<2) return "yesterday";
if($d<30) return "$d days ago";
$mo = floor($d/30);
if($mo<=1) return "a month ago";
$y = floor($mo/12);
if($y<1) return "$mo months ago";
if($y==1) return "a year ago";
return "$y years ago";
คุณสามารถใช้ส่วนขยาย TimeAgoซึ่งมีลักษณะดังนี้:
public static string TimeAgo(this DateTime dateTime)
{
string result = string.Empty;
var timeSpan = DateTime.Now.Subtract(dateTime);
if (timeSpan <= TimeSpan.FromSeconds(60))
{
result = string.Format("{0} seconds ago", timeSpan.Seconds);
}
else if (timeSpan <= TimeSpan.FromMinutes(60))
{
result = timeSpan.Minutes > 1 ?
String.Format("about {0} minutes ago", timeSpan.Minutes) :
"about a minute ago";
}
else if (timeSpan <= TimeSpan.FromHours(24))
{
result = timeSpan.Hours > 1 ?
String.Format("about {0} hours ago", timeSpan.Hours) :
"about an hour ago";
}
else if (timeSpan <= TimeSpan.FromDays(30))
{
result = timeSpan.Days > 1 ?
String.Format("about {0} days ago", timeSpan.Days) :
"yesterday";
}
else if (timeSpan <= TimeSpan.FromDays(365))
{
result = timeSpan.Days > 30 ?
String.Format("about {0} months ago", timeSpan.Days / 30) :
"about a month ago";
}
else
{
result = timeSpan.Days > 365 ?
String.Format("about {0} years ago", timeSpan.Days / 365) :
"about a year ago";
}
return result;
}
หรือใช้ปลั๊กอิน jQueryพร้อมส่วนขยายมีดโกนจาก Timeago
คุณสามารถลดภาระฝั่งเซิร์ฟเวอร์โดยดำเนินการตรรกะฝั่งไคลเอ็นต์นี้ ดูแหล่งที่มาในหน้า Digg บางหน้าสำหรับการอ้างอิง พวกเขามีเซิร์ฟเวอร์ปล่อยค่าเวลายุคที่ได้รับการประมวลผลโดย Javascript วิธีนี้คุณไม่จำเป็นต้องจัดการเขตเวลาของผู้ใช้ รหัสฝั่งเซิร์ฟเวอร์ใหม่จะเป็นดังนี้:
public string GetRelativeTime(DateTime timeStamp)
{
return string.Format("<script>printdate({0});</script>", timeStamp.ToFileTimeUtc());
}
คุณสามารถเพิ่มบล็อก NOSCRIPT ที่นั่นและเพียงแค่ทำการ ToString ()
นี่ฉันได้มาจากบล็อกของ Bill Gates ฉันต้องการค้นหามันในประวัติเบราว์เซอร์ของฉันและฉันจะให้ลิงก์แก่คุณ
รหัส Javascript ที่จะทำสิ่งเดียวกัน (ตามที่ร้องขอ):
function posted(t) {
var now = new Date();
var diff = parseInt((now.getTime() - Date.parse(t)) / 1000);
if (diff < 60) { return 'less than a minute ago'; }
else if (diff < 120) { return 'about a minute ago'; }
else if (diff < (2700)) { return (parseInt(diff / 60)).toString() + ' minutes ago'; }
else if (diff < (5400)) { return 'about an hour ago'; }
else if (diff < (86400)) { return 'about ' + (parseInt(diff / 3600)).toString() + ' hours ago'; }
else if (diff < (172800)) { return '1 day ago'; }
else {return (parseInt(diff / 86400)).toString() + ' days ago'; }
}
โดยทั่วไปคุณทำงานในไม่กี่วินาที ...
ฉันคิดว่ามีคำตอบจำนวนมากที่เกี่ยวข้องกับโพสต์นี้ แต่สามารถใช้สิ่งนี้ซึ่งใช้งานง่ายเช่นเดียวกับปลั๊กอินและยังสามารถอ่านได้ง่ายสำหรับโปรแกรมเมอร์ ส่งวันที่เฉพาะเจาะจงของคุณและรับค่าในรูปแบบสตริง:
public string RelativeDateTimeCount(DateTime inputDateTime)
{
string outputDateTime = string.Empty;
TimeSpan ts = DateTime.Now - inputDateTime;
if (ts.Days > 7)
{ outputDateTime = inputDateTime.ToString("MMMM d, yyyy"); }
else if (ts.Days > 0)
{
outputDateTime = ts.Days == 1 ? ("about 1 Day ago") : ("about " + ts.Days.ToString() + " Days ago");
}
else if (ts.Hours > 0)
{
outputDateTime = ts.Hours == 1 ? ("an hour ago") : (ts.Hours.ToString() + " hours ago");
}
else if (ts.Minutes > 0)
{
outputDateTime = ts.Minutes == 1 ? ("1 minute ago") : (ts.Minutes.ToString() + " minutes ago");
}
else outputDateTime = "few seconds ago";
return outputDateTime;
}
/**
* {@code date1} has to be earlier than {@code date2}.
*/
public static String relativize(Date date1, Date date2) {
assert date2.getTime() >= date1.getTime();
long duration = date2.getTime() - date1.getTime();
long converted;
if ((converted = TimeUnit.MILLISECONDS.toDays(duration)) > 0) {
return String.format("%d %s ago", converted, converted == 1 ? "day" : "days");
} else if ((converted = TimeUnit.MILLISECONDS.toHours(duration)) > 0) {
return String.format("%d %s ago", converted, converted == 1 ? "hour" : "hours");
} else if ((converted = TimeUnit.MILLISECONDS.toMinutes(duration)) > 0) {
return String.format("%d %s ago", converted, converted == 1 ? "minute" : "minutes");
} else if ((converted = TimeUnit.MILLISECONDS.toSeconds(duration)) > 0) {
return String.format("%d %s ago", converted, converted == 1 ? "second" : "seconds");
} else {
return "just now";
}
}
หากคุณต้องการที่จะมีเอาท์พุทเช่น"2 days, 4 hours and 12 minutes ago"
คุณจะต้องมีช่วงเวลา:
TimeSpan timeDiff = DateTime.Now-CreatedDate;
จากนั้นคุณสามารถเข้าถึงค่าที่คุณชอบ:
timeDiff.Days
timeDiff.Hours
ฯลฯ ...
ฉันจะให้วิธีส่วนขยายที่มีประโยชน์สำหรับเรื่องนี้และทำให้โค้ดอ่านง่ายขึ้น Int32
ครั้งแรกคู่ของวิธีการขยายสำหรับ
public static class TimeSpanExtensions {
public static TimeSpan Days(this int value) {
return new TimeSpan(value, 0, 0, 0);
}
public static TimeSpan Hours(this int value) {
return new TimeSpan(0, value, 0, 0);
}
public static TimeSpan Minutes(this int value) {
return new TimeSpan(0, 0, value, 0);
}
public static TimeSpan Seconds(this int value) {
return new TimeSpan(0, 0, 0, value);
}
public static TimeSpan Milliseconds(this int value) {
return new TimeSpan(0, 0, 0, 0, value);
}
public static DateTime Ago(this TimeSpan value) {
return DateTime.Now - value;
}
}
DateTime
จากนั้นหนึ่งสำหรับ
public static class DateTimeExtensions {
public static DateTime Ago(this DateTime dateTime, TimeSpan delta) {
return dateTime - delta;
}
}
ตอนนี้คุณสามารถทำสิ่งต่อไปนี้:
var date = DateTime.Now;
date.Ago(2.Days()); // 2 days ago
date.Ago(7.Hours()); // 7 hours ago
date.Ago(567.Milliseconds()); // 567 milliseconds ago