programing

를 사용하는 실제 타임스팬 개체입니다.몇 년 & .몇달.

jooyons 2023. 6. 14. 21:51
반응형

를 사용하는 실제 타임스팬 개체입니다.몇 년 & .몇달.

다음 두 가지 시나리오를 고려합니다.시나리오 1).오늘은 2012년 5월 1일, 시나리오 2)입니다.오늘은 2012년 9월 1일입니다.

이제, 우리가 웹 페이지에 누군가가 남긴 댓글에 대해 "이 댓글은 3개월 12일 전에 작성되었습니다."라고 적는 것을 고려해 보십시오.이 두 시나리오의 일 수는 문이 정확히 동일하더라도 항상 다릅니다.은 "3개월 12일"과 같습니다.102 days은 "3개월 12일"입니다.104 days!

이제, 제 요점을 요약하자면, 다른 예를 사용하여 2013년 1월 30일, 그리고 오늘이 2013년 3월 10일에 우리 사이트에 댓글을 남겼다고 합시다.실제 TimeSpan 개체는 이 상대 날짜를 알아야 하며 다음을 파악할 수 있습니다.

  • 3월에는 10일이 있고,
  • 1월에 1일(30일부터 31일까지 계산)이 있다는 것.
  • 2월은 몇 일이 있는지에 관계없이 한 달입니다(28일임에도 불구하고).

그래서, 그것은 10일 + 1일 + 1개월을 의미하고, 환산하면 다음과 같습니다.This comment was posted 1 Month and 11 Days ago.

이제 MS 스타일 TimeSpan 개체(또는 어떤 언어로든 TimeSpan 개체)를 사용했다면 1월 30일부터 3월 10일(39일)까지의 일수가 제공됩니다. TimeSpan 개체는 상대 날짜(TimeSpan을 얻기 위해 뺀 기준/초기 날짜)를 저장하지 않기 때문입니다. 몇 개월 및 며칠이 지났는지 묻는다면,한 달에 30일이 있다고 가정하거나 최악의 경우 평균 30일 이상이라고 가정하고 나머지는 일 단위로 반환합니다. 따라서 39일로 가려면 1개월 9일이 지났음을 알려줍니다.This comment was posted 1 Month and 9 Days ago 모두 날짜가 예, 사실을 TimeSpan을했습니다.두 시나리오 모두 시작 날짜와 현재/종료 날짜가 동일합니다. 예, Microsoft TimeSpan 개체는 2013년 2월을 고려해야 한다는 사실을 알리지 않음으로써 완전히 다른 시간 범위를 이틀 동안 제공했습니다.사실상, 그것은 우리에게 거짓말을 했습니다.

문제는, 사람들이 이것을 믿을 것이고, 그들이 어떤 인식을 가지고 있는지, 그들의 과거에 대한 인식이 어떻게 바뀔지, 그리고 그들이 그들 자신의 마음 속에서 과거의 사건들을 재구성하려고 할 때 그들이 내릴 수 있는 결정과 삶의 선택들을 누가 알겠는가 하는 것입니다.오늘날 모든 곳에 만연한 시간을 표현하는 것의 단점과 고유한 실패를 결코 눈치채지 못하거나 이해하지 못하는 동안.그들은 프로그래밍 언어가 지난달 30일, 29일 또는 28일 또는 비자 반대로 31일이 있었다는 것을 깨닫지 못하고(또는 신경 쓰지 않으며), 시간 범위를 늘리면 이것이 합산된다는 것을 이해하지 못할 것입니다.

이것이 이 게시물의 핵심 문제입니다.저는 대부분의 사람들이 이 차이에 대해 신경 쓰지 않을 것이라는 것을 이해합니다(그러나 우리 중 일부는 신경을 쓰고, 우리는 이것을 등에 업을 수 없습니다). 그리고 이것이 당신을 괴롭히지 않는다면, 괜찮습니다.그것이 저를 괴롭히지 않았으면 좋았을 텐데, 저는 시간과 스트레스와 실망을 좀 덜 수 있었을 것입니다.이 기능이 문제가 되지 않는 경우 이 기능을 사용하여 일반적으로 무시할 수 있는 정확도를 제공하는 대신 상대적인 시간(초에서 수년까지 1-6개 노드로 사용자 지정 가능)을 효율적으로 텍스트로 표시할 수 있습니다.

실망스럽게도 저는 만약 당신이 시간 간격을 가지고, 그리고 그렇게 한다면, 실제 시간 간격 물체가 없다는 것을 알아차렸습니다..years또는.months아무것도 얻지 못할 것이고, 오직 얻을 것입니다..days시간 범위 개체는 시간 범위가 생성된 월 또는 연도를 알려주는 어떤 내용도 전달하지 않기 때문에 값을 낮춥니다.따라서 1년에 걸쳐 그리고 심지어 윤년에 걸쳐 각 달의 일이 달라지기 때문에 몇 개월이 지났는지 결코 알 수 없습니다.

이에 대응하여 정확한 판독값을 얻기 위해 개발한 기능을 ASP.NET 웹 페이지에 게시하고 다음과 같은 내용을 반환할 수 있습니다.

4년 3개월 14일 15시간 18분 24초 전에 게시됨

나는 거기에 …이 있을 거라고 생각했습니다.

timeSpan.GetActualNumberOf[Months/Days/Hours/etc] (기준일은 반드시 제공되어야 합니다.

이 데이터 형식에 method 형식을 지정했지만 없습니다.

할 입니다. 은 꽤할 수 , " " " " " " " " " " " " " " " " " " " " " " " " " " " " " 은 매우 쉽게 계산할 수 있습니다. 그러면 위의 사랑스러운 문자열을 쉽게 계산할 수 있고,.year&.month존재할 것입니다!

업데이트: 아래 답변의 공식 답변 및 코드 사용 세부 정보, 100% 작업 답변 및 코드(전체), 정확하고 정확한 상대 시간/날짜, 근사치 없음에 대해 크게 확장 및 업데이트했습니다. 감사합니다.

다음은 평균 값을 사용하여 C#으로 이 확장 방법을 추가하는 방법입니다.

public static class TimeSpanExtensions
{
    public static int GetYears(this TimeSpan timespan)
    {
        return (int)(timespan.Days/365.2425);
    }
    public static int GetMonths(this TimeSpan timespan)
    {
        return (int)(timespan.Days/30.436875);
    }
}

당신이 찾고 있는 것은 사실 무엇이 아닙니다.TimeSpan나타내다. TimeSpan 구 을 기 기 준 로 하 않 눈 개 나 냅 타 니 다 로 수 금 간 고 지 저 값 을 , ▁of ▁repres ▁as ▁ticks ▁count 니 다 ▁interval ▁respect ▁a ents ▁without 냅 ▁an ▁base 구 나 ▁to ▁a타간DateTime또는Calendar.

새로운DateDifferencetype은 이 되는 이 더 가 있을 수 .DateTime 적표DateTime으로 리고선으로a.Calendar(CultureInfo는 문화정보입니다.)다양한 차이 성분(년, 월 등)을 계산하는 데 사용되는 Culture(현재 문화)

편집: 제가 보기에 노다 시간에는 이에 필요한 도구가 있을 수 있습니다. 클래스는 "[r] 인간의 시간 단위로 표현되는 기간: 시간, 일, 주, 월 등을 나타냅니다."Period.Between(then, now, PeriodUnits.AllUnits)인 것 . 복잡한 입니다. 하지만 그것은 필연적으로 훨씬 더 복잡한 수업입니다.TimeSpan노다 타임 위키의 주요 개념 페이지에서는 "인간이 시간을 어떻게 지저분하게 만드는지" 설명합니다.

천문학과 상대성 이론의 까다로운 부분은 제쳐두고, 인류는 여전히 협상하기 어려운 시간을 만들었습니다.만약 우리 모두가 시간에 대해 이야기하기 위해 유닉스 시대의 틱을 사용한다면, 노다 타임과 같은 라이브러리가 필요하지 않을 것입니다.

하지만, 우리는 몇 년, 몇 달, 며칠, 몇 주 동안 이야기하는 것을 좋아합니다. 그리고 어떤 이유에서인지 우리는 대략 태양이 가장 높은 시간대인 오후 12시를 좋아합니다.그래서 우리는 시간대가 있습니다.

뿐만 아니라, 몇 개월이 남았는지에 대해서는 모두 동의하지 않습니다.다른 문명들은 한 해를 나누는 다른 방법들을 생각해냈습니다. 그리고 시작할 몇 년 동안 다른 숫자들을 생각해냈습니다.이것들은 달력 시스템입니다.

음, 아무것도 없는 것보다 늦은 것이 낫습니다;)

모든 것을 주는 C# 함수

그리고 이것은 제가 수정한 버전입니다.

private string GetElapsedTime(DateTime from_date, DateTime to_date) {
int years;
int months;
int days;
int hours;
int minutes;
int seconds;
int milliseconds;

//------------------
// Handle the years.
//------------------
years = to_date.Year - from_date.Year;

//------------------------
// See if we went too far.
//------------------------
DateTime test_date = from_date.AddMonths(12 * years);

if (test_date > to_date)
{
    years--;
    test_date = from_date.AddMonths(12 * years);
}

//--------------------------------
// Add months until we go too far.
//--------------------------------
months = 0;

while (test_date <= to_date)
{
    months++;
    test_date = from_date.AddMonths(12 * years + months);
}

months--;

//------------------------------------------------------------------
// Subtract to see how many more days, hours, minutes, etc. we need.
//------------------------------------------------------------------
from_date = from_date.AddMonths(12 * years + months);
TimeSpan remainder = to_date - from_date;
days = remainder.Days;
hours = remainder.Hours;
minutes = remainder.Minutes;
seconds = remainder.Seconds;
milliseconds = remainder.Milliseconds;

return (years > 0 ? years.ToString() + " years " : "") +
       (months > 0 ? months.ToString() + " months " : "") +
       (days > 0 ? days.ToString() + " days " : "") +
       (hours > 0 ? hours.ToString() + " hours " : "") +
       (minutes > 0 ? minutes.ToString() + " minutes " : "");}

다음은 코드에 대한 주요 답변입니다. 날짜/시간 정확도, 초/분, 초/분 또는 초/분/일을 최대 년(6개의 부품/세그먼트 포함)까지 어디서나 얻을 수 있습니다.상위 2개를 지정하고 1년 이상 지난 경우 "1년 3개월 전"을 반환하고 나머지는 두 개의 세그먼트를 요청했기 때문에 반환하지 않습니다.몇 시간이 지나지 않은 경우 "2시간 1분 전"만 반환됩니다.물론 1, 2, 3, 4, 5 또는 6 세그먼트를 지정하는 경우에도 동일한 규칙이 적용됩니다(초, 분, 시간, 일, 월, 년은 6개 유형만 만들기 때문에 최대 6개).또한 1분 이상인지에 따라 "분" 대 "분"과 같은 문법 문제를 수정하며, 모든 유형에서 동일하게 생성된 "문자열"은 항상 문법적으로 정확합니다.

다몇 가지 사예입 다니는용. bAllowSegments표 . 즉,경우 i: 3이면 반환 문자열은 (예를 들어)... "3 years, 2 months and 13 days"되므로 시간,분및날짜인 동일한 하면 ("3")이 반환됩니다."4 days, 1 hour and 13 minutes ago"대신, 모든 것을 고려합니다!

이면 bAllowSegments " 2"를 합니다."3 years and 2 months" 6이 그리고 6(최대값)을 한다면,"3 years, 2 months, 13 days, 13 hours, 29 minutes and 9 seconds"하지만, 그렇게 될 것이라는 것을 상기하세요.NEVER RETURN와 것"0 years, 0 months, 0 days, 3 hours, 2 minutes and 13 seconds ago"상위 3개 세그먼트에는 날짜 데이터가 없으며 6개 세그먼트를 지정하더라도 무시하므로 걱정하지 마십시오. :).물론 0이 포함된 세그먼트가 있으면 문자열을 구성할 때 이를 고려하여 다음과 같이 표시됩니다."3 days and 4 seconds ago"그리고 "0시간" 부분을 무시합니다!맛있게 드시고 원하시면 댓글 달아주세요.

 Public Function RealTimeUntilNow(ByVal dt As DateTime, Optional ByVal bAllowSegments As Byte = 2) As String
  ' bAllowSegments identifies how many segments to show... ie: if 3, then return string would be (as an example)...
  ' "3 years, 2 months and 13 days" the top 3 time categories are returned, if bAllowSegments is 2 it would return
  ' "3 years and 2 months" and if 6 (maximum value) would return "3 years, 2 months, 13 days, 13 hours, 29 minutes and 9 seconds"
  Dim rYears, rMonths, rDays, rHours, rMinutes, rSeconds As Int16
  Dim dtNow = DateTime.Now
  Dim daysInBaseMonth = Date.DaysInMonth(dt.Year, dt.Month)

  rYears = dtNow.Year - dt.Year
  rMonths = dtNow.Month - dt.Month
  If rMonths < 0 Then rMonths += 12 : rYears -= 1 ' add 1 year to months, and remove 1 year from years.
  rDays = dtNow.Day - dt.Day
  If rDays < 0 Then rDays += daysInBaseMonth : rMonths -= 1
  rHours = dtNow.Hour - dt.Hour
  If rHours < 0 Then rHours += 24 : rDays -= 1
  rMinutes = dtNow.Minute - dt.Minute
  If rMinutes < 0 Then rMinutes += 60 : rHours -= 1
  rSeconds = dtNow.Second - dt.Second
  If rSeconds < 0 Then rSeconds += 60 : rMinutes -= 1

  ' this is the display functionality
  Dim sb As StringBuilder = New StringBuilder()
  Dim iSegmentsAdded As Int16 = 0

  If rYears > 0 Then sb.Append(rYears) : sb.Append(" year" & If(rYears <> 1, "s", "") & ", ") : iSegmentsAdded += 1
  If bAllowSegments = iSegmentsAdded Then GoTo parseAndReturn

  If rMonths > 0 Then sb.AppendFormat(rMonths) : sb.Append(" month" & If(rMonths <> 1, "s", "") & ", ") : iSegmentsAdded += 1
  If bAllowSegments = iSegmentsAdded Then GoTo parseAndReturn

  If rDays > 0 Then sb.Append(rDays) : sb.Append(" day" & If(rDays <> 1, "s", "") & ", ") : iSegmentsAdded += 1
  If bAllowSegments = iSegmentsAdded Then GoTo parseAndReturn

  If rHours > 0 Then sb.Append(rHours) : sb.Append(" hour" & If(rHours <> 1, "s", "") & ", ") : iSegmentsAdded += 1
  If bAllowSegments = iSegmentsAdded Then GoTo parseAndReturn

  If rMinutes > 0 Then sb.Append(rMinutes) : sb.Append(" minute" & If(rMinutes <> 1, "s", "") & ", ") : iSegmentsAdded += 1
  If bAllowSegments = iSegmentsAdded Then GoTo parseAndReturn

  If rSeconds > 0 Then sb.Append(rSeconds) : sb.Append(" second" & If(rSeconds <> 1, "s", "") & "") : iSegmentsAdded += 1

parseAndReturn:

  ' if the string is entirely empty, that means it was just posted so its less than a second ago, and an empty string getting passed will cause an error
  ' so we construct our own meaningful string which will still fit into the "Posted * ago " syntax...

  If sb.ToString = "" Then sb.Append("less than 1 second")

  Return ReplaceLast(sb.ToString.TrimEnd(" ", ",").ToString, ",", " and")

 End Function

물론 소스 문자열을 사용하는 "마지막 바꾸기" 함수와 바꿀 내용을 지정하는 인수, 바꿀 내용을 지정하는 다른 인수가 필요합니다. 그러면 해당 문자열의 마지막 항목만 대체됩니다.만약 당신이 그것을 가지고 있지 않거나 구현하고 싶지 않다면, 나는 내 것을 포함시켰기 때문에, 이것은 수정할 필요 없이 "있는 그대로" 작동할 것입니다.ReplaceLast 및 ReverseIt 기능은 더 이상 필요하지 않다는 것을 알고 있습니다(.net에 존재). 하지만 ReplaceLast 및 ReverseIt 기능은 .net 이전 날짜부터 적용되므로 날짜가 어떻게 표시되는지 양해해 주십시오(아직도 100% 작동하고, 10년 이상 사용하고 있으며, 버그가 없음을 보장할 수 있습니다)...:). 또한 VB6를 사용하는 경우 StrReverse를 사용할 수 있습니다.ReverseIt() 함수(확장 방법으로 제공)를 사용하는 대신 ReverseIt 확장 메서드)를 사용합니다.sReplacable을 실행하는 대신,ReverseIt, StrReverse(sReplacable)는 VB6 함수에 내장되어 있기 때문에 StrReverse(sReplacable)를 수행할 수 있습니다(그리고 정확히 동일한 작업을 수행하고 지정된 문자열을 반전하며 그 이상은 수행하지 않습니다).일반적인 ReverseIt 함수 대신 StrReverse()를 사용하는 경우 ReverseIt 함수/확장자를 자유롭게 삭제하십시오.레거시 ms-visual basic-dll 라이브러리를 가져오는 한 StrReverse() 기능을 .NET에서 사용할 수 있어야 합니다.어느 쪽이든 차이가 없습니다. 저는 StrReverse() 함수가 존재한다는 것을 알기도 전에 Reverse()를 작성했고, 그 이후로 습관적으로 사용해 왔습니다(내장된 일반 함수 StrReverse와 반대로 제 것을 사용할 실질적인 이유가 없음). 사실, StrReverse(또는 유사한 최신 버전).문자열 반전 함수의 NET 특정 버전)이 더 효율적으로 작성될 것입니다. :).건배.

<Extension()> _ 
Public Function ReplaceLast(ByVal sReplacable As String, ByVal sReplaceWhat As String, ByVal sReplaceWith As String) As String 
    ' let empty string arguments run, incase we dont know if we are sending and empty string or not. 
    sReplacable = sReplacable.ReverseIt 
    sReplacable = Replace(sReplacable, sReplaceWhat.ReverseIt, sReplaceWith.ReverseIt, , 1) ' only does first item on reversed version! 
    Return sReplacable.ReverseIt.ToString 
End Function 

<Extension()> _ 
Public Function ReverseIt(ByVal strS As String, Optional ByVal n As Integer = -1) As String 
    Dim strTempX As String = "", intI As Integer 

    If n > strS.Length Or n = -1 Then n = strS.Length 

    For intI = n To 1 Step -1 
        strTempX = strTempX + Mid(strS, intI, 1) 
    Next intI 

    ReverseIt = strTempX + Right(strS, Len(strS) - n) 

End Function 

. 4 및 를Net 4.5 및 사용CultureInfo클래스, 주어진 날짜에 월과 년을 추가할 수 있습니다.

DateTime datetime = DateTime.UtcNow;
int years = 15;
int months = 7;

DateTime yearsAgo = CultureInfo.InvariantCulture.Calendar.AddYears(datetime, -years);
DateTime monthsInFuture = CultureInfo.InvariantCulture.Calendar.AddMonths(datetime, months);

입력이 많기 때문에 확장 메서드를 만드는 것이 좋습니다.

public static DateTime AddYears(this DateTime datetime, int years)
{
    return CultureInfo.InvariantCulture.Calendar.AddYears(datetime, years);
}

public static DateTime AddMonths(this DateTime datetime, int months)
{
    return CultureInfo.InvariantCulture.Calendar.AddMonths(datetime, months);
}

DateTime yearsAgo = datetime.AddYears(-years);
DateTime monthsInFuture = datetime.AddMonths(months);

현재 TimeSpan은 실시간 범위 객체입니다. 즉, 2008년 1월 1일 오전 1시 31분에서 2008년 2월 3일 오전 6시 45분 사이의 시간은 2008년 2월 5일 오후 1시 45분에서 2008년 3월 9일 오후 6시 59분 사이의 시간과 동일합니다.당신이 찾고 있는 것은 실제로 두 데이트 시간의 차이입니다.

에 대해서는.Make Magic Happen. 예쁜 거 주세요.확실히 MS는 생각했습니다.이 딜마는 당신의 시스템의 특정한 요구를 충족시키기 위해 사람들이 당신을 프로그래머로 고용하는 이유입니다.만약 당신이 사용하고 있는 프레임워크가 완전히 모든 것을 수행한다면, 당신의 회사는 버튼 하나만 누르면 그들의 시스템이 완전히 형성되어 당신은 우리 프로그래머들과 함께 실업선에 서게 될 것입니다.

다음 방법은 프레임워크 날짜 계산을 기반으로 하고 Facebook의 방법처럼 읽을 수 있는 경과 시간 문자열을 반환하기 때문에 매우 신뢰할 수 있고 간단하다고 생각합니다.작은 포르투갈어 단어와 복수 처리에 대해 미안합니다, 저의 경우 그것은 필요했습니다.

public static string ElapsedTime(DateTime dtEvent)
{
    TimeSpan TS = DateTime.Now - dtEvent;

    int intYears = TS.Days / 365;
    int intMonths = TS.Days / 30;
    int intDays = TS.Days;
    int intHours = TS.Hours;
    int intMinutes = TS.Minutes;
    int intSeconds = TS.Seconds;

    if (intYears > 0) return String.Format("há {0} {1}", intYears, (intYears == 1) ? "ano" : "anos");
    else if (intMonths > 0) return String.Format("há {0} {1}", intMonths, (intMonths == 1) ? "mês" : "meses");
    else if (intDays > 0) return String.Format("há {0} {1}", intDays, (intDays == 1) ? "dia" : "dias");
    else if (intHours > 0) return String.Format("há ± {0} {1}", intHours, (intHours == 1) ? "hora" : "horas");
    else if (intMinutes > 0) return String.Format("há ± {0} {1}", intMinutes, (intMinutes == 1) ? "minuto" : "minutos");
    else if (intSeconds > 0) return String.Format("há ± {0} {1}", intSeconds, (intSeconds == 1) ? "segundo" : "segundos");
    else
    {
        return String.Format("em {0} às {1}", dtEvent.ToShortDateString(), dtEvent.ToShortTimeString());
    }
}

저는 수락된 답변을 받아 VB에서 변환했습니다.C#에 Net을 연결하고 몇 가지 수정/개선 작업도 수행했습니다.저는 문자열의 마지막 인스턴스를 대체하기 위해 사용되던 문자열 반전을 없애고, 문자열의 마지막 인스턴스를 보다 직접적으로 찾고 대체하는 확장 방법을 사용했습니다.

메소드 호출 방법의 예:

PeriodBetween(#2/28/2011#, DateTime.UtcNow, 6)

주 방법:

public static string PeriodBetween(DateTime then, DateTime now, byte numberOfPeriodUnits = 2)
{
    // Translated from VB.Net to C# from: https://stackoverflow.com/a/1956265

    // numberOfPeriodUnits identifies how many time period units to show.
    // If numberOfPeriodUnits = 3, function would return:
    //      "3 years, 2 months and 13 days"
    // If numberOfPeriodUnits = 2, function would return:
    //      "3 years and 2 months"
    // If numberOfPeriodUnits = 6, (maximum value), function would return:
    //      "3 years, 2 months, 13 days, 13 hours, 29 minutes and 9 seconds"

    if (numberOfPeriodUnits > 6 || numberOfPeriodUnits < 1)
    {
        throw new ArgumentOutOfRangeException($"Parameter [{nameof(numberOfPeriodUnits)}] is out of bounds. Valid range is 1 to 6.");
    }

    short Years = 0;
    short Months = 0;
    short Days = 0;
    short Hours = 0;
    short Minutes = 0;
    short Seconds = 0;
    short DaysInBaseMonth = (short)(DateTime.DaysInMonth(then.Year, then.Month));

    Years = (short)(now.Year - then.Year);

    Months = (short)(now.Month - then.Month);
    if (Months < 0)
    {
        Months += 12;
        Years--; // add 1 year to months, and remove 1 year from years.
    }

    Days = (short)(now.Day - then.Day);
    if (Days < 0)
    {
        Days += DaysInBaseMonth;
        Months--;
    }

    Hours = (short)(now.Hour - then.Hour);
    if (Hours < 0)
    {
        Hours += 24;
        Days--;
    }

    Minutes = (short)(now.Minute - then.Minute);
    if (Minutes < 0)
    {
        Minutes += 60;
        Hours--;
    }

    Seconds = (short)(now.Second - then.Second);
    if (Seconds < 0)
    {
        Seconds += 60;
        Minutes--;
    }

    // This is the display functionality.
    StringBuilder TimePeriod = new StringBuilder();
    short NumberOfPeriodUnitsAdded = 0;

    if (Years > 0)
    {
        TimePeriod.Append(Years);
        TimePeriod.Append(" year" + (Years != 1 ? "s" : "") + ", ");
        NumberOfPeriodUnitsAdded++;
    }

    if (numberOfPeriodUnits == NumberOfPeriodUnitsAdded)
    {
        goto ParseAndReturn;
    }

    if (Months > 0)
    {
        TimePeriod.AppendFormat(Months.ToString());
        TimePeriod.Append(" month" + (Months != 1 ? "s" : "") + ", ");
        NumberOfPeriodUnitsAdded++;
    }

    if (numberOfPeriodUnits == NumberOfPeriodUnitsAdded)
    {
        goto ParseAndReturn;
    }

    if (Days > 0)
    {
        TimePeriod.Append(Days);
        TimePeriod.Append(" day" + (Days != 1 ? "s" : "") + ", ");
        NumberOfPeriodUnitsAdded++;
    }

    if (numberOfPeriodUnits == NumberOfPeriodUnitsAdded)
    {
        goto ParseAndReturn;
    }

    if (Hours > 0)
    {
        TimePeriod.Append(Hours);
        TimePeriod.Append(" hour" + (Hours != 1 ? "s" : "") + ", ");
        NumberOfPeriodUnitsAdded++;
    }

    if (numberOfPeriodUnits == NumberOfPeriodUnitsAdded)
    {
        goto ParseAndReturn;
    }

    if (Minutes > 0)
    {
        TimePeriod.Append(Minutes);
        TimePeriod.Append(" minute" + (Minutes != 1 ? "s" : "") + ", ");
        NumberOfPeriodUnitsAdded++;
    }

    if (numberOfPeriodUnits == NumberOfPeriodUnitsAdded)
    {
        goto ParseAndReturn;
    }

    if (Seconds > 0)
    {
        TimePeriod.Append(Seconds);
        TimePeriod.Append(" second" + (Seconds != 1 ? "s" : "") + "");
        NumberOfPeriodUnitsAdded++;
    }

    ParseAndReturn:
    // If the string is empty, that means the datetime is less than a second in the past.
    // An empty string being passed will cause an error, so we construct our own meaningful
    // string which will still fit into the "Posted * ago " syntax.

    if (TimePeriod.ToString() == "")
    {
        TimePeriod.Append("less than 1 second");
    }

    return TimePeriod.ToString().TrimEnd(' ', ',').ToString().ReplaceLast(",", " and");
}

마지막 확장 방법 바꾸기:

public static string ReplaceLast(this string source, string search, string replace)
{
    int pos = source.LastIndexOf(search);

    if (pos == -1)
    {
        return source;
    }

    return source.Remove(pos, search.Length).Insert(pos, replace);
}

언급URL : https://stackoverflow.com/questions/1916358/a-real-timespan-object-with-years-months

반응형