J'ai écrit une fonction qui donnait un Je veux maintenant prolonger cette fonction en mois et en année, il sera donc en mesure d'imprimer: P> epoch code>, renvoie une chaîne qui affichera le temps relatif de l'heure et de la minute p> Par exemple: p> function toBeautyString(epochNow, epochNow){
var secDiff = Math.abs(epochNow - epochNow);
var milliInDay = 1000 * 60 * 60 * 24;
var milliInHour = 1000 * 60 * 60;
var nbDays = Math.round(secDiff/milliInDay);
var nbHour = Math.round(secDiff/milliInHour);
var relativeHour = (nbDays === 0) ? nbHour : nbHour-(nbDays*24);
relativeHour %= 24;
if(nbHour === 0){
nbDays += 1;
}else if(nbHour === (nbDays-1)*24){
nbDays -= 1;
}
var dayS = (nbDays > 1) ? "days" : "day";
var hourS = (relativeHour > 1) ? "hours" : "hour";
var fullString = "";
if(nbDays > 0){
fullString += nbDays + " " + dayS;
if(relativeHour > 0)
fullString += " ";
}
if(relativeHour > 0){
fullString += relativeHour + " " + hourS;
}
if(epochDate > epochNow){
return "Will be in " + fullString;
}else if ((epochDate === epochNow)
|| (relativeHour === 0 && nbDays === 0)){
return "Now";
}else{
return fullString + " ago";
}
}
5 Réponses :
Il est utile de reconnaître cela comme deux problèmes distincts: 1) Tranking le temps dans des morceaux individuels d'unités variables; 2) formater les morceaux et les rejoindre avec votre choix de virgules, conjonctions, etc. De cette façon, vous conservez votre logique de formatage de texte séparé de votre logique de calcul de temps.
#converts a time amount into a collection of time amounts of varying size.
#`increments` is a list that expresses the ratio of successive time units
#ex. If you want to split a time into days, hours, minutes, and seconds,
#increments should be [24,60,60]
#because there are 24 hours in a day, 60 minutes in an hour, etc.
#as an example, divideTime(100000, [24,60,60]) returns [1,3,46,40],
#which is equivalent to 1 day, 3 hours, 46 minutes, 40 seconds
def divideTime(amount, increments):
#base case: there's no increments, so no conversion is necessary
if len(increments) == 0:
return [amount]
#in all other cases, we slice a bit off of `amount`,
#give it to the smallest increment,
#convert the rest of `amount` into the next largest unit,
#and solve the rest with a recursive call.
else:
conversionRate = increments[-1]
smallestIncrement = amount % conversionRate
rest = divideTime(amount / conversionRate, increments[:-1])
return rest + [smallestIncrement]
def beautifulTime(amount):
names = ["year", "month", "day", "hour", "minute", "second"]
increments = [12, 30, 24, 60, 60]
ret = []
times = divideTime(amount, increments)
for i in range(len(names)):
time = times[i]
name = names[i]
#don't display the unit if the time is zero
#e.g. we prefer "1 year 1 second" to
#"1 year 0 months 0 days 0 hours 0 minutes 1 second"
if time == 0:
continue
#pluralize name if appropriate
if time != 1:
name = name + "s"
ret.append(str(time) + " " + name)
#there's only one unit worth mentioning, so just return it
if len(ret) == 1:
return ret[0]
#when there are two units, we don't need a comma
if len(ret) == 2:
return "{0} and {1}".format(ret[0], ret[1])
#for all other cases, we want a comma and an "and" before the last unit
ret[-1] = "and " + ret[-1]
return ", ".join(ret)
print beautifulTime(100000000)
#output: 3 years, 2 months, 17 days, 9 hours, 46 minutes, and 40 seconds
Y a-t-il un moyen d'obtenir le nombre exact? Même si c'est très complexe à faire, je serai heureux de comprendre comment cela peut être fait.
Je ne suis pas un expert en temps, je ne sais donc pas comment obtenir le nombre exact. Je ne suis même pas sûr d'un nombre exact possible. Le temps est très difficile à faire, car il y a tellement d'exceptions près et de modifications et d'éléments «Gotcha». C'est presque toujours une meilleure idée de trouver une bibliothèque existante que de faire la vôtre.
D'accord, je suis simplement curieux, quelqu'un sur tellement probablement une bibliothèque existante! J'espère qu'il verra cette question!
Il y a beaucoup de bibliothèques; L'objet de date intégré dans JavaScript permet en fait beaucoup d'abus (par exemple, la date dans le constructeur peut être en dehors de sa plage) et comprend des éléments tels que l'UTC et la lumière du jour, des localisations de temps d'économie d'été ...
fractions d'une journée (heures, minutes, secondes), voire des jours eux-mêmes, ne sont pas un problème. Le problème est que la longueur de "un mois" varie entre 28 et 31 jours. P> Je vous donne un exemple: P> permet de dire aujourd'hui est 28 févr. 2013 Et vous souhaitez calculer TOBeauTystring (28 janvier 2013) CODE>: P> today: 1 Mar 2013
toBeautyString(28 Jan 2013)
expected answer 1 month and 1 days ago
Hmm tobeautysstring (28 janvier 2013) hier a donné une valeur de 1 mois et il y a 4 jours il y a 1 mois. Aussi aujourd'hui n'est plus 1 mars 2013 est le 2 mars 2013.
La sortie dépend du moment où vous exécutez le code (sur la valeur de maintenant). Ce n'est pas un gros problème, juste une entrée cachée que vous devez prendre en compte.
1 mois à l'avenir, la date sera la même, le mois sera de 1 unité plus élevé (avec une enveloppe éventuelle à janvier). Cela peut signifier 28 jours, 29 ou 30, ou 31, en fonction du / courant / mois. Il y a 1 mois, la date était la même, mais le mois était inférieur de 1 unité (ou enveloppe à décembre). Sa longueur dépend du nombre de jours au / le passé / mois. Où est le problème?.
Vous pouvez utiliser la classe // ----------------------------------------------------------------------
public void DateDiffSample( DateTime epoch )
{
DateDiff dateDiff = new DateDiff( DateTime.Now, epoch );
Console.WriteLine( "{0} ago", dateDiff.GetDescription( 4 ) );
// > 1 Year 4 Months 12 Days 12 Hours ago
} // DateDiffSample
Aussi de manière exhaustive dans d'autres réponses, votre code ne peut pas être facilement étendu en raison des longueurs de mois variable. Donc, on ne peut tout simplement pas supposer que le mois soit 30 jours.
Pour avoir une différence lisible par l'homme, vous devez soustraire des dates lisibles humaines. P>
Je le ferais comme Ceci (JavaScript, pour correspondre à la question): P>
function toBeautyString(then) {
var nowdate = new Date();
var thendate = new Date(then * 1000);
//finding the human-readable components of the date.
var y = nowdate.getFullYear() - thendate.getFullYear();
var m = nowdate.getMonth() - thendate.getMonth();
var d = nowdate.getDate() - thendate.getDate();
var h = nowdate.getHours() - thendate.getHours();
var mm = nowdate.getMinutes() - thendate.getMinutes();
var s = nowdate.getSeconds() - thendate.getSeconds();
//back to second grade math, now we must now 'borrow'.
if(s < 0) {
s += 60;
mm--;
}
if(mm < 0) {
mm += 60;
h--;
}
if(h < 0) {
h += 24;
d--;
}
if(d < 0) {
//here's where we take into account variable month lengths.
var a = thendate.getMonth();
var b;
if(a <= 6) {
if(a == 1) b = 28;
else if(a % 2 == 0) b = 31;
else b = 30;
}
else if(b % 2 == 0) b = 30;
else b = 31;
d += b;
m--;
}
if(m < 0) {
m += 12;
y--;
}
//return "y years, m months, d days, h hours, mm minutes and s seconds ago."
}
Il ne prévoit également pas de temps d'économie de jour, ce qui entraînera une heure manquante (ou restes) lorsqu'il va chevaucher la journée dans laquelle vous ajoutez ou soustrayez une heure ...
Évité, aussi plus efficace que ma mise en œuvre; Mais veuillez corriger les fautes de frappe lorsque vous déclarez Nowdate code> et Thendate code> ( Var Date Nowdated code>: mot date code> non nécessaire). En outre, cela échoue si le thengate n'est pas dans le passé ... Facile à réparer, de même que des années de saut et de sauts de DST.
Deux fonctions: une pour calculer la différence, et une autre pour le montrer (inspirée de la réponse de Kevin). Fonctionne pour tous mes tests, prend en compte des durées de mois, facile à traduire et fonctionne également autour du temps d'économie de jour.
En ce qui concerne le temps d'économie de jour: vous ne devriez probablement pas le prendre en compte pour des périodes plus courtes, par exemple 1 jour ou moins. Vous pouvez également le mentionner dans la jolie chaîne imprimée "plus 1 heure perdue / gagnée à DST".
Que diriez-vous de vous montrer votre
tobeautysstring code> code? Je préfère étendre cela puis écrivez-vous une nouvelle fonction de zéro.S'il vous plaît dites-nous quelle langue vous utilisez. Est-ce que c'est JavaScript?