2017-03-08 83 views
1

我想寫一個轉換器從毫秒到最高可能的時間值,然後達到0,x值。毫秒到達0之前的最高可能時間值,xx

讓我來舉例說明。

讓我們假設你有1500ms這將導致1,5secs,因爲其可能的最高數字值導致0,x

所以不同的例子是

10ms = 10,0ms 
100ms = 100,0ms 
1000ms = 1,0sec 
10000ms = 10,0sec 
100000ms = 1,6min 
1000000ms = 16,0min 
10000000ms = 2,7hours 

(該方法應該或多或少是無止境的,所以從數小時到數天,數週,數月,到幾年,到幾十年,等...)

有沒有.net的方法呢?

+0

相當簡單 - 在某個超單元低於1之前定義最小數量ms的列表/字典,然後使用要應用適當的轉換 –

+0

我會爲您希望支持的每個轉換(ms到sec,sec到min,min到hr,hr到days等)創建一個轉換方法,然後創建一個方法來調用轉換爲了。每次轉換後,如果新值小於1,請停止並返回以前的值。繼續前進,直到達到您想要支持的最大時間範圍,然後返回結果。 TimeSpan課程將幫助所有轉換達數年,然後您將需要進行自己的轉換。 – Marc

回答

1

像下面

public static string ConversionMethod(UInt64 ms) 
{ 
    // change output format as needed 
    string format = "######.###"; 

    var cutoffs = new List<UInt64>() { 
     1000, // second 
     60000, // minute 
     3600000, // hour 
     86400000, // day 
     604800000, // week = day * 7 
     2592000000, // month = day * 30 
     31536000000, // year = day * 365 
     315360000000, // decade = year * 10 
     3153600000000, // century = decade * 10 (100 years) 
     31536000000000, // millenia = century * 10 (1000 years) 
     31536000000000000 // megayear = year * 100000 
     // 18446744073709551615 // UInt64 MaxValue 
     // 31536000000000000000 // gigayear = year * 100000000 
    }; 

    var postfix = new List<String>() { 
     "second", 
     "minute", 
     "hour", 
     "day", 
     "week", 
     "month", 
     "year", 
     "decade", 
     "century", 
     "millenia", 
     "megayear" 
    }; 

    // The above are listed from smallest to largest for easy reading, 
    // but the comparisons need to be made from largest to 
    // smallest (in the loop below) 
    cutoffs.Reverse(); 
    postfix.Reverse(); 

    int count = 0; 

    foreach (var cutoff in cutoffs) 
    { 
     if (ms > cutoff) 
     { 
      return ((decimal)((decimal)ms/(decimal)cutoff)).ToString(format) + " " + postfix[count]; 
     } 

     count++; 
    } 

    return ms + " ms"; 
} 

轉換爲分數是有點髒,可能要清除該向上。此外,您必須決定如何處理閏年(以及閏秒)等。

1

雖然不是最終的解決方案,也許TimeSpan可以幫助你實現你正在尋找的東西。 但要注意的是,TimeSpan僅支持到TotalDays

var timespan = TimeSpan.FromMilliseconds(1500); 
var seconds = timespan.TotalSeconds; // equals: 1.5 
0

看來TimeSpan類是滿足您需求的最接近的東西,但顯然它並不完全符合您的要求。我就帶它會是這個樣子:

public static string ScientificNotationTimespan(int milliseconds) 
{ 
    var timeSpan = new TimeSpan(0, 0, 0, 0, milliseconds); 
    var totalDays = timeSpan.TotalDays; 
    if (totalDays < 7) 
    { 
     if (timeSpan.TotalDays > 1) return timeSpan.TotalDays.ToString() + " days"; 
     if (timeSpan.TotalHours > 1) return timeSpan.TotalHours.ToString() + " hours"; 
     if (timeSpan.TotalMinutes > 1) return timeSpan.TotalMinutes.ToString() + " minutes"; 
     if (timeSpan.TotalSeconds > 1) return timeSpan.TotalSeconds.ToString() + " seconds"; 
     return milliseconds.ToString() + "milliseconds"; 
    } 

    var weeks = totalDays/7; 
    //How long is a month? 28, 29, 30 or 31 days? 
    var years = totalDays/365; 
    if (years < 1) return weeks.ToString() + " weeks"; 
    var decades = years/10; 
    if (decades < 1) return years.ToString() + " years"; 
    var centuries = decades/10; 
    if (centuries < 1) return decades.ToString() + " decades"; 
    var millenia = centuries/10; 
    if (millenia < 1) return centuries.ToString() + " centuries"; 
    return millenia.ToString() + " millenia"; 
} 
+0

實際上,千禧年的一部分將無法工作,因爲千禧年中有太多毫秒可以適應整數。 –

-1

這裏是解決多年,使用DateTime和公曆(意爲閏年,日曆個月)個月。然後它使用已提交的TimeSpan解決方案。

static string ToMostNonZeroTime(long ms) { 
    const int hundretsNanosecondsInMillisecond = 10000; 
    long ticks = (long)ms * hundretsNanosecondsInMillisecond; 
    var dt = new DateTime(ticks); 

    if((dt.Year - 1) > 0) { // starts with 1 
     double daysToYear = (dt.DayOfYear - 1) * 1.0/(DateTime.IsLeapYear(dt.Year) ? 366 : 365); 
     daysToYear += dt.Year - 1; 
     return $"{daysToYear:0.0} years"; 
    } 
    if((dt.Month - 1) > 0) { 
     double daysToMonth = (dt.Day - 1) * 1.0/DateTime.DaysInMonth(dt.Year, dt.Month); 
     daysToMonth += dt.Day - 1; 
     return $"{daysToMonth:0.0} months"; 
    } 
    // can use TimeSpan then: 
    var ts = TimeSpan.FromMilliseconds(ms); 
    if(ts.TotalDays >= 1) 
     return $"{ts.TotalDays:0.0} days"; 
    if(ts.TotalHours >= 1) 
     return $"{ts.TotalHours:0.0} hours"; 
    if(ts.TotalMinutes >= 1) 
     return $"{ts.TotalMinutes:0.0} minutes"; 
    if(ts.TotalSeconds >= 1) 
     return $"{ts.TotalSeconds:0.0} seconds"; 
    return $"{ms} milliseconds"; 
} 

它打印

100ms: 100 milliseconds 
1000ms: 1.0 seconds 
10000ms: 10.0 seconds 
100000ms: 1.7 minutes 
1000000ms: 16.7 minutes 
10000000ms: 2.8 hours 
100000000ms: 1.2 days 
1000000000ms: 11.6 days 
20000000000ms: 19.6 months 
200000000000ms: 6.3 years 

看一看https://ideone.com/QZHOM4

+0

這是'DateTime'的一個不好的用法 - 我非常懷疑,如果你認爲它在1月1日開始的話,「年月是否是一個有用的衡量標準。 –

+0

@JonSkeet是的,我也懷疑這一點,因爲我不確定這種格式的目的(一些魔法世界?)。只是猜測,如果這是我們的世界。 – Artyom