it-swarm.com.de

Die beste Möglichkeit, Zeit (hh: mm) in einer Datenbank zu speichern

Ich möchte Zeiten in einer Datenbanktabelle speichern, muss aber nur die Stunden und Minuten speichern. Ich weiß, ich könnte DATETIME verwenden und die anderen Komponenten des Datums ignorieren als ich eigentlich brauche?

84
Matthew Dresser

Sie können es als ganze Zahl der Minuten nach Mitternacht speichern:

z.B. 

0 = 00:00 
60 = 01:00
252 = 04:12

Sie müssen jedoch etwas Code schreiben, um die Zeit wiederherzustellen, aber das sollte nicht schwierig sein.

114
BigJump

Wenn Sie SQL Server 2008 oder höher verwenden, beachten Sie den Datentyp TIME . SQLTeam-Artikel mit weiteren Anwendungsbeispielen.

48
WebMatrix

DATETIME Start DATETIME Ende

Ich bitte Sie, stattdessen zwei DATETIME-Werte zu verwenden, die so etwas wie event_start und event_end beschriftet sind. 

Zeit ist ein komplexes Geschäft

Der Großteil der Welt hat jetzt das Denery-basierte Messsystem für die meisten Messungen verwendet, zu Recht oder zu Unrecht. Das ist insgesamt gut, denn zumindest können wir uns alle darauf einigen, dass ein g, ein ml, ein Kubikzentimeter ist. Zumindest ungefähr so. Das metrische System hat viele Mängel, aber zumindest ist es international durchgehend fehlerhaft.

Mit der Zeit haben wir jedoch; 1000 Millisekunden pro Sekunde, 60 Sekunden bis zu einer Minute, 60 Minuten bis zu einer Stunde, 12 Stunden für jeden halben Tag, etwa 30 Tage pro Monat, die je nach Monat und Jahr variieren, jedes Land hat seine Zeitverschiebung von den anderen , die Art und Weise, wie die Zeit in jedem Land formatiert wird, ist unterschiedlich.

Es ist viel zu verdauen, aber bei einem so komplexen Szenario ist es unmöglich, eine einfache Lösung zu finden.

Einige Ecken können geschnitten werden, aber es gibt einige, bei denen es klüger ist,

Obwohl die erste Antwort darauf hinweist, dass Sie eine ganze Zahl von Minuten nach Mitternacht speichern, erscheint das durchaus vernünftig. Ich habe jedoch gelernt, dies auf die harte Tour zu vermeiden.

Die Gründe für die Implementierung von zwei DATETIME-Werten sprechen für eine Erhöhung der Genauigkeit, Auflösung und Rückmeldung. 

Dies ist alles sehr praktisch, wenn das Design unerwünschte Ergebnisse liefert.

Mache ich mehr Daten als nötig?

Es mag zunächst so aussehen, als würden mehr Informationen gespeichert, als ich brauche, aber es gibt einen guten Grund, diesen Treffer zu wagen. 

Das Speichern dieser zusätzlichen Informationen spart mir auf Dauer fast immer Zeit und Mühe, weil ich unweigerlich feststelle, dass jemand, der sich darüber informiert hat, wie lange etwas gedauert hat, zusätzlich wissen möchte, wann und wo die Veranstaltung stattgefunden hat.

Es ist ein riesiger Planet

In der Vergangenheit habe ich mich schuldig gemacht, zu ignorieren, dass es außer meinem eigenen Land noch andere Länder auf diesem Planeten gibt. Es schien damals eine gute Idee zu sein, aber dies hat IMMER zu Problemen, Kopfschmerzen und Zeitverschwendung auf der ganzen Linie geführt. IMMER alle Zeitzonen berücksichtigen.

C #

Eine DateTime wird in C # als String dargestellt. Die ToString-Methode (String-Format) ist kompakt und einfach zu lesen. 

Z.B.

new TimeSpan(EventStart.Ticks - EventEnd.Ticks).ToString("h'h 'm'm 's's'")

SQL Server

Auch wenn Sie Ihre Datenbank getrennt von Ihrer Anwendungsschnittstelle lesen, können Sie dateTimes auf einen Blick lesen und Berechnungen für sie einfach durchführen.

Z.B.

SELECT DATEDIFF(MINUTE, event_start, event_end)

ISO8601-Datumsstandard

Wenn Sie SQLite verwenden, haben Sie dies nicht, verwenden Sie stattdessen ein Textfeld und speichern Sie es im ISO8601-Format, z.

2013-01-27T12: 30: 00 + 0000

Anmerkungen: 

  • Diese verwendet 24 Stunden *

  • Der +0000-Teil von ISO8601 kartiert direkt in einer GPS-Koordinate. Es lohnt sich daher zu überlegen, ob es sich lohnt, Längen, Breitengrad und Höhe zusammen mit den Daten zu speichern. Dies wird in der Anwendung variieren.

  • ISO8601 ist ein internationales Format. 

  • Das Wiki ist sehr gut für weitere Details unter http://en.wikipedia.org/wiki/ISO_8601 .

  • Datum und Uhrzeit werden in internationaler Zeit gespeichert und der Versatz wird erfasst, je nachdem, wo auf der Welt die Uhrzeit gespeichert wurde. 

Nach meiner Erfahrung ist es immer notwendig, das vollständige Datum und die Uhrzeit zu speichern, unabhängig davon, ob ich denke, dass es zu Beginn des Projekts der Fall ist. ISO8601 ist eine sehr gute und zukunftssichere Methode.

Zusätzliche Beratung kostenlos

Es lohnt sich auch, Events zu einer Kette zusammenzufassen. Z.B. Wenn ein Rennen aufgezeichnet wird, kann das gesamte Ereignis nach Rennfahrer, Race_Circuit, Circuit_checkpoints und Circuit_laps gruppiert werden.

Nach meiner Erfahrung ist es auch ratsam, zu ermitteln, wer die Aufzeichnung gespeichert hat. Entweder als separate Tabelle, die über einen Trigger gefüllt wird, oder als zusätzliche Spalte in der ursprünglichen Tabelle. 

Je mehr du reinlegst, desto mehr kommst du raus

Ich verstehe vollkommen den Wunsch, mit dem Platz so sparsam wie möglich zu sein, aber ich würde das selten tun, um Informationen zu verlieren.

Als Faustregel bei Datenbanken gilt, wie der Titel sagt, eine Datenbank kann Ihnen nur so viel sagen, wie Daten dafür vorliegen, und es kann sehr kostspielig sein, historische Daten durchzublättern und Lücken zu füllen.

Die Lösung ist, es beim ersten Mal richtig zu machen. Dies ist sicherlich leichter gesagt als getan, aber Sie sollten jetzt einen tieferen Einblick in das effektive Datenbankdesign haben und folglich die Chance haben, es beim ersten Mal richtig zu machen.

Je besser Ihr anfänglicher Entwurf ist, desto kostengünstiger werden die Reparaturen später.

Ich sage nur das alles, denn wenn ich in der Zeit zurückgehen könnte, würde ich es mir selbst sagen, wenn ich dort bin.

11

Speichern Sie einfach eine reguläre Datumszeit und ignorieren Sie alles andere. Warum verbringen Sie zusätzliche Zeit damit, Code zu schreiben, der ein int lädt, manipuliert und in eine datetime konvertiert, wenn Sie einfach eine datetime laden könnten?

10
Seth

da Sie es nicht erwähnt haben, wenn Sie sich auf SQL Server 2008 befinden, können Sie den Zeitdatentyp verwenden, andernfalls verwenden Sie Minuten seit Mitternacht

4
SQLMenace

Ich würde sie in eine Ganzzahl (HH * 3600 + MM * 60) konvertieren und so speichern. Kleine Speichergröße und trotzdem einfach zu handhaben.

2
Glen Solsberry

SQL Server speichert die Zeit tatsächlich als Bruchteile eines Tages. Beispiel: 1 ganzer Tag = Wert von 1. 12 Stunden ist ein Wert von 0.5.

Wenn Sie den Zeitwert ohne Verwendung eines DATETIME-Typs speichern möchten, würde das Speichern der Zeit in dezimaler Form dies erfordern, während die Konvertierung in ein DATETIME einfach ist.

Zum Beispiel:

SELECT CAST(0.5 AS DATETIME)
--1900-01-01 12:00:00.000

Wenn Sie den Wert als DECIMAL (9,9) speichern, werden 5 Byte benötigt. Wenn die Genauigkeit jedoch nicht von größter Bedeutung ist, würde eine REAL nur 4 Byte verbrauchen. In jedem Fall kann die Gesamtberechnung (d. H. Die mittlere Zeit) leicht anhand numerischer Werte berechnet werden, nicht jedoch anhand der Daten/Zeit-Typen.

2
Taylor Gerring

Wenn Sie MySQL verwenden, verwenden Sie einen Feldtyp TIME und die zugehörige Funktionalität, die mit TIME geliefert wird.

00:00:00 ist das Standard-Unix-Zeitformat.

Wenn Sie die Tabellen von Hand zurückschauen müssen, können ganze Zahlen verwirrender sein als ein tatsächlicher Zeitstempel.

2
Syntax

Anstelle von Minuten nach Mitternacht speichern wir sie als 24-Stunden-Uhr, als SMALLINT.

09:12 = 912 ... 14:15 = 1415

wenn Sie wieder in "vom Menschen lesbare Form" konvertieren, fügen Sie einfach einen Doppelpunkt ein: zwei Zeichen von rechts. Linkes Pad mit Nullen, wenn Sie müssen. Speichert die Mathematik auf jede Art und Weise und verwendet einige wenige Bytes (im Vergleich zu varchar) und erzwingt, dass der Wert numerisch ist (nicht alphanumerisch).

Ziemlich doof ... aber es sollte schon seit vielen Jahren einen TIME-Datentyp in MS SQL geben, IMHO ... 

1
Kristen

Ich denke, Sie fragen nach einer Variablen, die die Minuten als Zahl speichert. Dies kann mit den verschiedenen Typen von Integer-Variablen erfolgen:

SELECT 9823754987598 AS MinutesInput

In Ihrem Programm können Sie dies einfach in der gewünschten Form anzeigen, indem Sie Folgendes berechnen:

long MinutesInAnHour = 60;

long MinutesInADay = MinutesInAnHour * 24;

long MinutesInAWeek = MinutesInADay * 7;


long MinutesCalc = long.Parse(rdr["MinutesInput"].toString()); //BigInt converts to long. rdr is an SqlDataReader.   


long Weeks = MinutesCalc / MinutesInAWeek;

MinutesCalc -= Weeks * MinutesInAWeek;


long Days = MinutesCalc / MinutesInADay;

MinutesCalc -= Days * MinutesInADay;


long Hours = MinutesCalc / MinutesInAnHour;

MinutesCalc -= Hours * MinutesInAnHour;


long Minutes = MinutesCalc;

Es tritt ein Problem auf, wenn Sie die Verwendung der Effizienz verlangen. Wenn Sie jedoch keine Zeit haben, verwenden Sie einfach einen nullfähigen BigInt, um Ihren Minutenwert zu speichern.

Ein Wert von null bedeutet, dass die Zeit noch nicht aufgezeichnet wurde.

Nun werde ich es in Form einer Rundreise in den Weltraum erklären.

Leider speichert eine Tabellenspalte nur einen einzigen Typ. Daher müssen Sie für jeden Typ eine neue Tabelle erstellen, wenn dies erforderlich ist.

Zum Beispiel:

  • Wenn MinutesInput = 0 ..255 ist, verwenden Sie TinyInt (Konvertieren wie oben beschrieben).

  • Wenn MinutesInput = 256 ..131071 ist, verwenden Sie SmallInt (Hinweis: Der Min Wert von SmallInt ist -32,768. Negieren Sie daher und fügen Sie 32768 hinzu, und speichern Sie den Wert .__ vollen Bereich vor dem Konvertieren wie oben verwenden).

  • Wenn MinutesInput = 131072 ..8589934591, verwenden Sie Int (Hinweis: Negieren Sie und fügen Sie ggf. 2147483648 hinzu).

  • Wenn MinutesInput = 8589934592 ..36893488147419103231, dann verwenden Sie BigInt (Hinweis: Fügen Sie nach Bedarf 9223372036854775808 hinzu).

  • Wenn MinutesInput> 36893488147419103231, dann würde ich persönlich VARCHAR (X) verwenden, um X nach Bedarf zu erhöhen, da ein Zeichen ein Byte ist. Ich werde Diese Antwort zu einem späteren Zeitpunkt erneut lesen müssen, um dies vollständig zu beschreiben .__ (oder vielleicht kann ein anderer Stackoverflowee diese Antwort beenden).

Da für jeden Wert zweifellos ein eindeutiger Schlüssel erforderlich ist, wird die Effizienz der Datenbank nur sichtbar, wenn der Bereich der gespeicherten Werte eine gute Mischung zwischen sehr klein (nahe 0 Minuten) und sehr hoch (größer als 8589934591) ist. 

Bis die Werte, die gespeichert werden, tatsächlich eine Zahl größer als 36893488147419103231 erreichen, können Sie auch eine einzige BigInt-Spalte zur Darstellung Ihrer Minuten verwenden, da Sie kein Int mit einem eindeutigen Bezeichner verschwenden müssen und ein anderes Int zum Speichern des Minutenwerts.

1

Versuchen Sie es mit Smalldatetime. Es kann Ihnen zwar nicht das geben, was Sie möchten, aber es hilft Ihnen bei Ihren zukünftigen Anforderungen bei der Datums-/Zeitmanipulation.

1
MarlonRibunal

Sind Sie sicher, dass Sie nur die Stunden und Minuten benötigen werden? Wenn Sie etwas Sinnvolles damit tun möchten (z. B. Berechnungszeiträume zwischen zwei derartigen Datenpunkten), wenn Sie keine Informationen über Zeitzonen und DST haben, kann dies zu falschen Ergebnissen führen. Zeitzonen gelten in Ihrem Fall möglicherweise nicht, aber DST wird dies sicherlich tun.

1
mghie

Die Zeitersparnis im UTC-Format kann besser helfen, als von Kristen vorgeschlagen.

Stellen Sie sicher, dass Sie die 24-Stunden-Uhr verwenden, da in UTC kein Meridian AM oder PM verwendet werden kann.

Beispiel:

  • 04:12 - 0412
  • 10:12 - 1012
  • 2:28 PM - 1428
  • 11:56 PM - 2356

Es ist immer noch vorzuziehen, das vierstellige Standardformat zu verwenden. 

0
balamurugavel

Speichern Sie die ticks als long/bigint, die derzeit in Millisekunden gemessen wird. Der aktualisierte Wert kann durch Anzeigen des Werts TimeSpan.TicksPerSecond ermittelt werden.

Die meisten Datenbanken verfügen über einen DateTime-Typ, der die Uhrzeit automatisch als Ticks hinter den Kulissen speichert. Bei einigen Datenbanken, z. SqlLite, das Speichern von Ticks kann eine Möglichkeit sein, das Datum zu speichern.

Die meisten Sprachen erlauben die einfache Konvertierung von TicksTimeSpanTicks.

Beispiel

In C # wäre der Code:

long TimeAsTicks = TimeAsTimeSpan.Ticks;

TimeAsTimeSpan = TimeSpan.FromTicks(TimeAsTicks);

Seien Sie sich jedoch bewusst, denn im Fall von SqlLite, das nur eine kleine Anzahl verschiedener Typen bietet, sind; INT, REAL und VARCHAR Die Anzahl der Teilstriche muss als Zeichenfolge oder als zwei INT-Zellen zusammen gespeichert werden. Dies liegt daran, dass INT eine 32-Bit-Nummer ist, während BIGINT eine 64-Bit-Nummer ist. 

Hinweis

Meine persönliche Präferenz wäre jedoch, Datum und Uhrzeit als ISO8601-Zeichenfolge zu speichern.

0