Apa cara terbaik untuk mengubah detik menjadi waktu (Jam: Menit: Detik: Milidetik)?

290

Apa cara terbaik untuk mengubah detik menjadi waktu (Jam: Menit: Detik: Milidetik)?

Katakanlah saya memiliki 80 detik, apakah ada kelas / teknik khusus di .NET yang memungkinkan saya untuk mengubah format 80 detik itu menjadi (00h: 00m: 00s: 00ms) seperti DateTime atau sesuatu?

John Saunders
sumber

Jawaban:

565

Untuk .Net <= 4.0 Gunakan kelas TimeSpan.

TimeSpan t = TimeSpan.FromSeconds( secs );

string answer = string.Format("{0:D2}h:{1:D2}m:{2:D2}s:{3:D3}ms", 
                t.Hours, 
                t.Minutes, 
                t.Seconds, 
                t.Milliseconds);

(Seperti dicatat oleh Inder Kumar Rathore) Untuk .NET> 4.0 Anda dapat menggunakan

TimeSpan time = TimeSpan.FromSeconds(seconds);

//here backslash is must to tell that colon is
//not the part of format, it just a character that we want in output
string str = time .ToString(@"hh\:mm\:ss\:fff");

(Dari Nick Molyneux) Pastikan bahwa detik kurang dari TimeSpan.MaxValue.TotalSecondsuntuk menghindari pengecualian.

Curtis Shipley
sumber
using System;Kelas berada di System.TimeSpan.
fbmd
61

Untuk .NET> 4.0 dapat Anda gunakan

TimeSpan time = TimeSpan.FromSeconds(seconds);

//here backslash is must to tell that colon is
//not the part of format, it just a character that we want in output
string str = time .ToString(@"hh\:mm\:ss\:fff");

atau jika Anda ingin format waktu tanggal maka Anda juga dapat melakukan ini

TimeSpan time = TimeSpan.FromSeconds(seconds);
DateTime dateTime = DateTime.Today.Add(time);
string displayTime = dateTime.ToString("hh:mm:tt");

Untuk lebih lanjut Anda dapat memeriksa String Format TimeSpan Kustom

Inder Kumar Rathore
sumber
2
Anda tidak perlu TimeSpan untuk menambahkan detik ke DateTime. Cukup gunakan DateTime.AddSeconds ().
Evgeni Nabokov
@MehdiDehghani untuk format 24 jam, Anda harus menggunakan 'HH' bukannya 'hh'
Inder Kumar Rathore
@InderKumarRathore Saya sedang berbicara tentang solusi pertama Anda, HHtidak valid di sana.
Mehdi Dehghani
@MehdiDehghani bisakah Anda tolong apa yang salah karena sudah 3 tahun saya tidak punya kode.NET/C#
Inder Kumar Rathore
1
@InderKumarRathore .ToString(@"hh\:mm\:ss\:fff");sudah dalam 24hrformat. HHtidak valid di sana dengan input seperti itu ( kesalahannya adalahInput string was not in a correct format. )
Mehdi Dehghani
23

Jika Anda tahu Anda memiliki beberapa detik, Anda dapat membuat nilai TimeSpan dengan memanggil TimeSpan.FromSeconds:

 TimeSpan ts = TimeSpan.FromSeconds(80);

Anda kemudian dapat memperoleh jumlah hari, jam, menit, atau detik. Atau gunakan salah satu kelebihan ToString untuk menampilkannya dengan cara apa pun yang Anda suka.

Jim Mischel
sumber
16

Saya melakukan beberapa tolok ukur untuk melihat apa cara tercepat dan ini adalah hasil dan kesimpulan saya. Saya menjalankan setiap metode 10 juta kali dan menambahkan komentar dengan waktu rata-rata per lari.

Jika input milidetik Anda tidak terbatas pada satu hari (hasil Anda mungkin 143: 59: 59,999), ini adalah opsi, dari yang lebih cepat ke yang lebih lambat:

// 0.86 ms
static string Method1(int millisecs)
{
    int hours = millisecs / 3600000;
    int mins = (millisecs % 3600000) / 60000;
    // Make sure you use the appropriate decimal separator
    return string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}", hours, mins, millisecs % 60000 / 1000, millisecs % 1000);
}

// 0.89 ms
static string Method2(int millisecs)
{
    double s = millisecs % 60000 / 1000.0;
    millisecs /= 60000;
    int mins = millisecs % 60;
    int hours = millisecs / 60;
    return string.Format("{0:D2}:{1:D2}:{2:00.000}", hours, mins, s);
}

// 0.95 ms
static string Method3(int millisecs)
{
    TimeSpan t = TimeSpan.FromMilliseconds(millisecs);
    // Make sure you use the appropriate decimal separator
    return string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}",
        (int)t.TotalHours,
        t.Minutes,
        t.Seconds,
        t.Milliseconds);
}

Jika input milidetik Anda terbatas pada satu hari (hasil Anda tidak akan pernah lebih besar dari 23: 59: 59,999), ini adalah opsi, dari yang lebih cepat ke yang lebih lambat:

// 0.58 ms
static string Method5(int millisecs)
{
    // Fastest way to create a DateTime at midnight
    // Make sure you use the appropriate decimal separator
    return DateTime.FromBinary(599266080000000000).AddMilliseconds(millisecs).ToString("HH:mm:ss.fff");
}

// 0.59 ms
static string Method4(int millisecs)
{
    // Make sure you use the appropriate decimal separator
    return TimeSpan.FromMilliseconds(millisecs).ToString(@"hh\:mm\:ss\.fff");
}

// 0.93 ms
static string Method6(int millisecs)
{
    TimeSpan t = TimeSpan.FromMilliseconds(millisecs);
    // Make sure you use the appropriate decimal separator
    return string.Format("{0:D2}:{1:D2}:{2:D2}.{3:D3}",
        t.Hours,
        t.Minutes,
        t.Seconds,
        t.Milliseconds);
}

Jika input Anda hanya beberapa detik , metode ini sedikit lebih cepat. Sekali lagi, jika input detik Anda tidak terbatas pada satu hari (hasil Anda mungkin 143: 59: 59):

// 0.63 ms
static string Method1(int secs)
{
    int hours = secs / 3600;
    int mins = (secs % 3600) / 60;
    secs = secs % 60;
    return string.Format("{0:D2}:{1:D2}:{2:D2}", hours, mins, secs);
}

// 0.64 ms
static string Method2(int secs)
{
    int s = secs % 60;
    secs /= 60;
    int mins = secs % 60;
    int hours = secs / 60;
    return string.Format("{0:D2}:{1:D2}:{2:D2}", hours, mins, s);
}

// 0.70 ms
static string Method3(int secs)
{
    TimeSpan t = TimeSpan.FromSeconds(secs);
    return string.Format("{0:D2}:{1:D2}:{2:D2}",
        (int)t.TotalHours,
        t.Minutes,
        t.Seconds);
}

Dan jika input detik Anda terbatas pada satu hari (hasil Anda tidak akan pernah lebih besar dari 23:59:59):

// 0.33 ms
static string Method5(int secs)
{
    // Fastest way to create a DateTime at midnight
    return DateTime.FromBinary(599266080000000000).AddSeconds(secs).ToString("HH:mm:ss");
}

// 0.34 ms
static string Method4(int secs)
{
    return TimeSpan.FromSeconds(secs).ToString(@"hh\:mm\:ss");
}

// 0.70 ms
static string Method6(int secs)
{
    TimeSpan t = TimeSpan.FromSeconds(secs);
    return string.Format("{0:D2}:{1:D2}:{2:D2}",
        t.Hours,
        t.Minutes,
        t.Seconds);
}

Sebagai komentar terakhir, izinkan saya menambahkan bahwa saya melihat bahwa string.Formatsedikit lebih cepat jika Anda menggunakan D2bukan 00.

Andrew
sumber
8

Konstruktor TimeSpan memungkinkan Anda untuk lulus dalam hitungan detik. Cukup mendeklarasikan variabel tipe TimeSpan jumlah detik. Ex:

TimeSpan span = new TimeSpan(0, 0, 500);
span.ToString();
Jim Petkus
sumber
4

Saya sarankan Anda menggunakan TimeSpankelas untuk ini.

public static void Main(string[] args)
{
    TimeSpan t = TimeSpan.FromSeconds(80);
    Console.WriteLine(t.ToString());

    t = TimeSpan.FromSeconds(868693412);
    Console.WriteLine(t.ToString());
}

Keluaran:

00:01:20
10054.07:43:32
Oliver Friedrich
sumber
4

Di VB.NET, tetapi sama di C #:

Dim x As New TimeSpan(0, 0, 80)
debug.print(x.ToString())
' Will print 00:01:20
Stefan
sumber
2

Untuk .NET <4.0 (mis: Unity ) Anda dapat menulis metode ekstensi untuk memiliki TimeSpan.ToString(string format)perilaku seperti .NET> 4.0

public static class TimeSpanExtensions
{
    public static string ToString(this TimeSpan time, string format)
    {
        DateTime dateTime = DateTime.Today.Add(time);
        return dateTime.ToString(format);
    }
}

Dan dari mana saja dalam kode Anda, Anda dapat menggunakannya seperti:

var time = TimeSpan.FromSeconds(timeElapsed);

string formattedDate = time.ToString("hh:mm:ss:fff");

Dengan cara ini Anda dapat memformat TimeSpanobjek apa pun dengan hanya memanggil ToString dari mana pun kode Anda.

Ege Aydın
sumber
1

Mengapa orang membutuhkan TimeSpan DAN DateTime jika kita memiliki DateTime.AddSeconds ()?

var dt = new DateTime(2015, 1, 1).AddSeconds(totalSeconds);

Tanggal arbitrer. totalSeconds bisa lebih besar dari 59 dan itu adalah dobel. Kemudian Anda dapat memformat waktu Anda seperti yang Anda inginkan menggunakan DateTime.ToString ():

dt.ToString("H:mm:ss");

Ini tidak berfungsi jika totalSeconds <0 atau> 59:

new DateTime(2015, 1, 1, 0, 0, totalSeconds)
Evgeni Nabokov
sumber
0
private string ConvertTime(double miliSeconds)
{
    var timeSpan = TimeSpan.FromMilliseconds(totalMiliSeconds);
    // Converts the total miliseconds to the human readable time format
    return timeSpan.ToString(@"hh\:mm\:ss\:fff");
}

//Uji

    [TestCase(1002, "00:00:01:002")]
    [TestCase(700011, "00:11:40:011")]
    [TestCase(113879834, "07:37:59:834")]
    public void ConvertTime_ResturnsCorrectString(double totalMiliSeconds, string expectedMessage)
    {
        // Arrange
        var obj = new Class();;

        // Act
        var resultMessage = obj.ConvertTime(totalMiliSeconds);

        // Assert
        Assert.AreEqual(expectedMessage, resultMessage);
    }
Moh Rezaee
sumber
3
1. OP meminta konversi dari detik, bukan milidetik. 2. Bagaimana jawaban Anda lebih baik daripada jawaban yang saat ini diterima?
vesan
0

untuk mendapatkan total detik

var i = TimeSpan.FromTicks(startDate.Ticks).TotalSeconds;

dan untuk mendapatkan datetime dari detik

var thatDateTime = new DateTime().AddSeconds(i)
unos baghaii
sumber
0

Ini akan kembali dalam format jj: mm: dd

 public static string ConvertTime(long secs)
    {
        TimeSpan ts = TimeSpan.FromSeconds(secs);
        string displayTime = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}";
        return displayTime;
    }
ATUL SHARMA
sumber
Anda tidak harus menguji ini. ConvertTime(80)pengembalian 0:1:20dan ConvertTime(61)pengembalian 0:1:1, keduanya h:m:s. Menggunakan interpolasi string juga menghasilkan kode yang lebih panjang daripada ToString(), seperti yang digunakan dalam jawaban lain, dan juga membuatnya lebih sulit untuk memvisualisasikan panjang string yang diformat.
BACON