1 - 366 arasında yılın gününü hesaplamak için javascript'i nasıl kullanırım? Örneğin:
- 3 Ocak olmalıdır 3 .
- 1 Şubat 32 olmalı .
1 - 366 arasında yılın gününü hesaplamak için javascript'i nasıl kullanırım? Örneğin:
Yanıtlar:
OP'nin düzenlemesinin ardından:
var now = new Date();
var start = new Date(now.getFullYear(), 0, 0);
var diff = now - start;
var oneDay = 1000 * 60 * 60 * 24;
var day = Math.floor(diff / oneDay);
console.log('Day of year: ' + day);
Düzenleme: Yukarıdaki kod başarısız olur ne zaman nowmart 26 ve 29 Ekim arasında bir tarihtir now'ın zamanında 1 am önce (örneğin 00:59:59). Bunun nedeni kodun yaz saati uygulamasını hesaba katmamasıdır. Bunu telafi etmelisiniz :
var now = new Date();
var start = new Date(now.getFullYear(), 0, 0);
var diff = (now - start) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
var oneDay = 1000 * 60 * 60 * 24;
var day = Math.floor(diff / oneDay);
console.log('Day of year: ' + day);
Math.floorNisan ayında belirli bir günün ardından bana sürekli olarak beklenenden 1 gün daha kısa bir sonuç verdi. Math.ceilbeklendiği gibi çalıştı, ancak Math.roundbunun yerine kullanmanızın tavsiye edildiğini gördüm .
new Date(2014, 0, 1), new Date(2014, 0, 0)buradaki gibi değil, kullanacaksınız . Bu kasıtlı mı? Belki de new Date(2014, 0, 0)geri döneceği gibi bir gün izinli olmanın açıklaması budur 12/31/2013.
.setUTCHoursve Date.UTC()daha güvenilir bir çözüm.
ceilyerine kullanmaktır floor, bu size 1 Ocak = 1 olan bir numaralandırma sistemi verecektir. 1 Ocak = 0 istiyorsanız ( floorsize vereceği gibi), nihai sonucunuzdan 1 çıkarın.
var diff = now - start + (start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000;
Bu, tüm ülkelerde Gün Işığından Yararlanma Saati değişikliklerinde geçerlidir (yukarıdaki "öğlen" Avustralya'da geçerli değildir):
Date.prototype.isLeapYear = function() {
var year = this.getFullYear();
if((year & 3) != 0) return false;
return ((year % 100) != 0 || (year % 400) == 0);
};
// Get Day of Year
Date.prototype.getDOY = function() {
var dayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
var mn = this.getMonth();
var dn = this.getDate();
var dayOfYear = dayCount[mn] + dn;
if(mn > 1 && this.isLeapYear()) dayOfYear++;
return dayOfYear;
};
getDay()olarak değiştirilmesi gerekiyor getDate(). İlki, günü değil haftanın gününü (0 = Pazar. 6 = Cumartesi) döndürür.
DST'ye tabi olmadığı için kimsenin UTC'yi kullanmayı düşünmemesini çok ilginç buluyorum. Bu nedenle, aşağıdakileri öneriyorum:
function daysIntoYear(date){
return (Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) - Date.UTC(date.getFullYear(), 0, 0)) / 24 / 60 / 60 / 1000;
}
Aşağıdakilerle test edebilirsiniz:
[new Date(2016,0,1), new Date(2016,1,1), new Date(2016,2,1), new Date(2016,5,1), new Date(2016,11,31)]
.forEach(d =>
console.log(`${d.toLocaleDateString()} is ${daysIntoYear(d)} days into the year`));
Artık yıl 2016 için hangi çıktılar ( http://www.epochconverter.com/days/2016 kullanılarak doğrulanmıştır ):
1/1/2016 is 1 days into the year
2/1/2016 is 32 days into the year
3/1/2016 is 61 days into the year
6/1/2016 is 153 days into the year
12/31/2016 is 366 days into the year
function doyToDate(doy, year) { return new Date(year, 0, doy); }
new Date(8640000000000000), hala daha küçüktür Number.MAX_SAFE_INTEGER. bu yanıta bakın: stackoverflow.com/a/11526569/18511
Date.prototype.dayOfYear= function(){
var j1= new Date(this);
j1.setMonth(0, 0);
return Math.round((this-j1)/8.64e7);
}
alert(new Date().dayOfYear())
Neyse ki bu soru içinde bulunduğunuz günün sayısının gerekli olup olmadığını belirtmiyor ve bu cevaba yer bırakıyor.
Ayrıca bazı cevaplar (diğer sorular için de) artık yıl problemlerine sahipti veya Date nesnesini kullandı. Javascript'in Date object1 Ocak 1970'in her iki tarafında yaklaşık 285616 yılı (100.000.000 gün) kapsamasına rağmen , farklı tarayıcılarda (özellikle 0'dan 99'a kadar) her türlü beklenmedik tarih tutarsızlığından bıktım . Nasıl hesaplayacağımı da merak ediyordum.
Bir basit ve her şeyden yazdığı Yani, küçük algoritma hesaplamak için doğru ( ilerisini düşünerek Gregoryen : 2004 (madde 4.3.2.1), bu yüzden / Astronomik / ISO 8601 yıl0 var ve artık yıl olup negatif yıl desteklenmektedir Yılın gününü) dayalı yıl , ay ve gün .
O Not AD/BCgösterimde, yıl 0 AD / BC yok: yerine yıl 1 BCsıçrama yıllık olduğunu! BC notasyonunu hesaba katmanız gerekiyorsa, önce (aksi takdirde pozitif) yıl değerinden bir yıl çıkarın !!
Kısa devre bitmask-modulo leapYear algoritmasını değiştirdim (javascript için) ve ofsetlerin bit bazında aranması için sihirli bir sayı buldum (bu, jan ve feb hariç, bu nedenle 10 * 3 bit (30 bit, daha az 31 bit, böylece bitshift'e güvenli bir şekilde başka bir karakter kaydedebiliriz >>>)).
Ne ayın ne de günün olabileceğini unutmayın 0. Sadece bu denklemi gerekiyorsa o Bunun anlamı şu anki gün (kullanarak besleme .getMonth()) sadece kaldırmak gerekir --dan --m.
Bunun geçerli bir tarih varsaydığını unutmayın (hata denetimi sadece birkaç karakter daha fazladır).
function dayNo(y,m,d){
return --m*31-(m>1?(1054267675>>m*3-6&7)-(y&3||!(y%25)&&y&15?0:1):0)+d;
}
<!-- some examples for the snippet -->
<input type=text value="(-)Y-M-D" onblur="
var d=this.value.match(/(-?\d+)[^\d]+(\d\d?)[^\d]+(\d\d?)/)||[];
this.nextSibling.innerHTML=' Day: ' + dayNo(+d[1], +d[2], +d[3]);
" /><span></span>
<br><hr><br>
<button onclick="
var d=new Date();
this.nextSibling.innerHTML=dayNo(d.getFullYear(), d.getMonth()+1, d.getDate()) + ' Day(s)';
">get current dayno:</button><span></span>
İşte doğru aralık doğrulamasına sahip sürüm .
function dayNo(y,m,d){
return --m>=0 && m<12 && d>0 && d<29+(
4*(y=y&3||!(y%25)&&y&15?0:1)+15662003>>m*2&3
) && m*31-(m>1?(1054267675>>m*3-6&7)-y:0)+d;
}
<!-- some examples for the snippet -->
<input type=text value="(-)Y-M-D" onblur="
var d=this.value.match(/(-?\d+)[^\d]+(\d\d?)[^\d]+(\d\d?)/)||[];
this.nextSibling.innerHTML=' Day: ' + dayNo(+d[1], +d[2], +d[3]);
" /><span></span>
Yine, bir satır, ancak okunabilirlik için (ve aşağıdaki açıklamayı) 3 satıra böldüm.
Son satır yukarıdaki işlevle aynıdır, ancak (aynı) leapYear algoritması önceki bir kısa devre bölümüne (gün-sayı hesaplamasından önce) taşınır, çünkü aynı zamanda bir ayda ne kadar gün olduğunu bilmek gerekir. verilen (artık) yıl.
Ortadaki çizgi, başka bir sihirli sayı kullanarak belirli bir (artık) yılda belirli bir ay için doğru ofset numarasını (maksimum gün sayısı için) hesaplar : çünkü 31-28=3ve 3sadece 2 bit, sonra 12*2=24bit, 12 ayın tümünü saklayabiliriz. Toplama, çıkarma işleminden daha hızlı olabileceğinden, ofseti ekleriz (çıkarmak yerine 31). Şubat için artık yıl karar dalından kaçınmak için, bu sihirli arama numarasını anında değiştiriyoruz.
Bu bizi (oldukça açık) ilk satırla bırakır: ayın ve tarihin geçerli sınırlar içinde olduğunu kontrol eder ve falsearalık hatası durumunda bize bir dönüş değeri sağlar (bu işlevin de 0 döndüremeyeceğini unutmayın, çünkü 1 ocak 0000 kolay hata kontrollerinin yapılmasından, hala 1. gün) 'dir: if(r=dayNo(/*y, m, d*/)){}.
(Ay ve gün olmayabilir bu şekilde kullanılırsa 0), sonra bir değiştirebilirsiniz --m>=0 && m<12için m>0 && --m<12(başka kömürü tasarruf).
Onun 'için mevcut haliyle parçacığını yazdığınız nedeni 0 tabanlı ay değerleri için, biri sadece kaldırmak için ihtiyacı olduğu --gelen --m.
Ekstra:
Unutmayın, ayda sadece maksimum güne ihtiyacınız varsa bu günün aylık algoritmasını kullanmayın. Bu durumda daha verimli bir algoritma var (çünkü sadece ay Şubat olduğunda leepYear'a ihtiyacımız var) Bu soruyu cevap olarak gönderdim: JavaScript ile bir aydaki gün sayısını belirlemenin en iyi yolu nedir? .
Date.prototype.dayNo = function(){ var y = this.getFullYear(); var m = this.getMonth()+1; var d = this.getDate(); return --m*31-(m>1?(1054267675>>m*3-6&7)-(y&3||!(y%25)&&y&15?0:1):0)+d; };
+1dan this.getMonth()+1kaldırmak eğer --dan --m. DÜZENLE Yani, yapardım (bir kütüphane için):Date.prototype.dayNo = function(){ var y=this.getFullYear(), m=this.getMonth(); return m*31-(m>1?(1054267675>>m*3-6&7)-(y&3||!(y%25)&&y&15?0:1):0)+this.getDate(); };
2^31 - 2016yıllar sonra js muhtemelen biraz modası geçmiş olacak.
:)sonra hiç test etmedim Ama o zamana kadar en azından tahmin edilebilir ve tutarlı sonuçlar verecek haha. EDIT , sadece teorinin iyiliği için, leapyear için daha yavaş geleneksel all-modulo algo kullanarak, aralık 2 ^ 53'e kadar genişletilebilir. Ay arama algo sınırlayıcı faktör değildir.
Tekerleği yeniden icat etmek istemiyorsanız, mükemmel tarih-fns (node.js) kitaplığını kullanabilirsiniz:
var getDayOfYear = require('date-fns/get_day_of_year')
var dayOfYear = getDayOfYear(new Date(2017, 1, 1)) // 1st february => 32
Pekala, eğer seni doğru anlıyorsam, artık yılda 366, yoksa 365 istiyorsun, değil mi? Bir yıl, 4'e eşit olarak bölünebiliyorsa artık bir yıldır, ancak 400 ile bölünemezse 100 ile bölünemez:
function daysInYear(year) {
if(year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
// Leap year
return 366;
} else {
// Not a leap year
return 365;
}
}
Bu durumda, yerleşik bir yöntem olduğunu düşünmüyorum; bunu yapmanız gerekecek:
function daysInFebruary(year) {
if(year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
// Leap year
return 29;
} else {
// Not a leap year
return 28;
}
}
function dateToDay(date) {
var feb = daysInFebruary(date.getFullYear());
var aggregateMonths = [0, // January
31, // February
31 + feb, // March
31 + feb + 31, // April
31 + feb + 31 + 30, // May
31 + feb + 31 + 30 + 31, // June
31 + feb + 31 + 30 + 31 + 30, // July
31 + feb + 31 + 30 + 31 + 30 + 31, // August
31 + feb + 31 + 30 + 31 + 30 + 31 + 31, // September
31 + feb + 31 + 30 + 31 + 30 + 31 + 31 + 30, // October
31 + feb + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, // November
31 + feb + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, // December
];
return aggregateMonths[date.getMonth()] + date.getDate();
}
(Evet, aslında bunu kopyalamadan veya yapıştırmadan yaptım. Kolay bir yolu varsa delireceğim)
:)
Bu, yıl içindeki içinde bulunulan günü bulmanın basit bir yoludur ve artık yılları sorunsuz bir şekilde hesaba katmalıdır:
JavaScript:
Math.round((new Date().setHours(23) - new Date(new Date().getYear()+1900, 0, 1, 0, 0, 0))/1000/60/60/24);
Google Apps Komut Dosyasında Javascript:
Math.round((new Date().setHours(23) - new Date(new Date().getYear(), 0, 1, 0, 0, 0))/1000/60/60/24);
Bu kodun birincil eylemi, cari yılda geçen milisaniye sayısını bulmak ve ardından bu sayıyı günlere dönüştürmektir. İçinde bulunduğumuz yılda geçen milisaniye sayısı, new Date(new Date().getYear()+1900, 0, 1, 0, 0, 0)(Javascript) veya new Date(new Date().getYear(), 0, 1, 0, 0, 0)(Google Apps Komut Dosyası) ile elde edilen cari yılın ilk gününün ilk saniyesinin milisaniye sayısını milisaniyeden çıkararak bulunabilir. ile bulundu günün 23. saatinin new Date().setHours(23). Güncel tarihi 23. saate ayarlamanın amacı, yılın gününün doğru bir şekilde yuvarlanmasını sağlamaktır Math.round().
İçinde bulunduğunuz yılın milisaniye sayısını elde ettiğinizde, milisaniyeyi saniyeye dönüştürmek için 1000'e bölerek, ardından saniyeyi dakikaya dönüştürmek için 60'a bölerek, ardından dakikayı saate dönüştürmek için 60'a bölerek bu zamanı günlere dönüştürebilirsiniz. ve son olarak saati günlere dönüştürmek için 24'e bölerek.
Not: Bu gönderi, Google Apps Komut Dosyasında uygulanan JavaScript ve JavaScript arasındaki farkları hesaba katmak için düzenlendi. Ayrıca, cevap için daha fazla bağlam eklendi.
.setHoursyöntemi ilk tarih nesnesinde kullandığım ve ikinci tarih nesnesi ile günün saatini belirttiğim için gün ışığından yararlanma saatinden 1 saatlik bir değişiklik bu hesaplamada kullanılan Date nesnelerinin saatlerini etkilemeyecektir.
Bunun daha basit olduğunu düşünüyorum:
var date365 = 0;
var currentDate = new Date();
var currentYear = currentDate.getFullYear();
var currentMonth = currentDate.getMonth();
var currentDay = currentDate.getDate();
var monthLength = [31,28,31,30,31,30,31,31,30,31,30,31];
var leapYear = new Date(currentYear, 1, 29);
if (leapYear.getDate() == 29) { // If it's a leap year, changes 28 to 29
monthLength[1] = 29;
}
for ( i=0; i < currentMonth; i++ ) {
date365 = date365 + monthLength[i];
}
date365 = date365 + currentDay; // Done!
Bu yöntem, saat dilimi sorununu ve yaz saati uygulamasını dikkate alır.
function dayofyear(d) { // d is a Date object
var yn = d.getFullYear();
var mn = d.getMonth();
var dn = d.getDate();
var d1 = new Date(yn,0,1,12,0,0); // noon on Jan. 1
var d2 = new Date(yn,mn,dn,12,0,0); // noon on input date
var ddiff = Math.round((d2-d1)/864e5);
return ddiff+1;
}
( buradan aldı )
Ayrıca bu kemana bakın
Math.round ((new Date (). SetHours (23) - new Date (new Date (). GetFullYear (), 0, 1, 0, 0, 0)) / 1000/86400);
yanıtı daha da optimize eder.
Dahası, setHours (23) veya son fakat iki sıfırı sonradan başka bir değere değiştirerek, başka bir saat dilimiyle ilgili yılın gününü sağlayabilir. Örneğin, Amerika'da bulunan bir kaynağı Avrupa'dan almak için.
Math.floor((Date.now() - Date.parse(new Date().getFullYear(), 0, 0)) / 86400000)
bu benim çözümüm
Okunabilir bir tane yaptım ve işi çok hızlı bir şekilde yapacak, aynı zamanda JS Date nesnelerini farklı saat dilimleriyle ele aldım.
Saat dilimleri, DST, artık saniyeler ve Artık yıllar için epeyce test senaryosu ekledim.
PS ECMA-262, UTC'den farklı olarak artık saniyeleri yok sayar. Bunu gerçek UTC kullanan bir dile dönüştürürseniz, sadece 1 'e ekleyebilirsiniz oneDay.
// returns 1 - 366
findDayOfYear = function (date) {
var oneDay = 1000 * 60 * 60 * 24; // A day in milliseconds
var og = { // Saving original data
ts: date.getTime(),
dom: date.getDate(), // We don't need to save hours/minutes because DST is never at 12am.
month: date.getMonth()
}
date.setDate(1); // Sets Date of the Month to the 1st.
date.setMonth(0); // Months are zero based in JS's Date object
var start_ts = date.getTime(); // New Year's Midnight JS Timestamp
var diff = og.ts - start_ts;
date.setDate(og.dom); // Revert back to original date object
date.setMonth(og.month); // This method does preserve timezone
return Math.round(diff / oneDay) + 1; // Deals with DST globally. Ceil fails in Australia. Floor Fails in US.
}
// Tests
var pre_start_dst = new Date(2016, 2, 12);
var on_start_dst = new Date(2016, 2, 13);
var post_start_dst = new Date(2016, 2, 14);
var pre_end_dst_date = new Date(2016, 10, 5);
var on_end_dst_date = new Date(2016, 10, 6);
var post_end_dst_date = new Date(2016, 10, 7);
var pre_leap_second = new Date(2015, 5, 29);
var on_leap_second = new Date(2015, 5, 30);
var post_leap_second = new Date(2015, 6, 1);
// 2012 was a leap year with a leap second in june 30th
var leap_second_december31_premidnight = new Date(2012, 11, 31, 23, 59, 59, 999);
var january1 = new Date(2016, 0, 1);
var january31 = new Date(2016, 0, 31);
var december31 = new Date(2015, 11, 31);
var leap_december31 = new Date(2016, 11, 31);
alert( ""
+ "\nPre Start DST: " + findDayOfYear(pre_start_dst) + " === 72"
+ "\nOn Start DST: " + findDayOfYear(on_start_dst) + " === 73"
+ "\nPost Start DST: " + findDayOfYear(post_start_dst) + " === 74"
+ "\nPre Leap Second: " + findDayOfYear(pre_leap_second) + " === 180"
+ "\nOn Leap Second: " + findDayOfYear(on_leap_second) + " === 181"
+ "\nPost Leap Second: " + findDayOfYear(post_leap_second) + " === 182"
+ "\nPre End DST: " + findDayOfYear(pre_end_dst_date) + " === 310"
+ "\nOn End DST: " + findDayOfYear(on_end_dst_date) + " === 311"
+ "\nPost End DST: " + findDayOfYear(post_end_dst_date) + " === 312"
+ "\nJanuary 1st: " + findDayOfYear(january1) + " === 1"
+ "\nJanuary 31st: " + findDayOfYear(january31) + " === 31"
+ "\nNormal December 31st: " + findDayOfYear(december31) + " === 365"
+ "\nLeap December 31st: " + findDayOfYear(leap_december31) + " === 366"
+ "\nLast Second of Double Leap: " + findDayOfYear(leap_second_december31_premidnight) + " === 366"
);
Önceki her ayın günlerini ekleyerek hesaplamalar yapan bir çözüm sunmak istiyorum:
function getDayOfYear(date) {
var month = date.getMonth();
var year = date.getFullYear();
var days = date.getDate();
for (var i = 0; i < month; i++) {
days += new Date(year, i+1, 0).getDate();
}
return days;
}
var input = new Date(2017, 7, 5);
console.log(input);
console.log(getDayOfYear(input));
Bu şekilde artık yılların ve gün ışığından yararlanma tasarrufunun ayrıntılarını yönetmek zorunda kalmazsınız.
UTC zaman damgalarını kullanan bir alternatif. Ayrıca diğerlerinin de belirttiği gibi, ayda 1'i gösteren gün 0 yerine 1'dir. Bununla birlikte, ay 0'dan başlar.
var now = Date.now();
var year = new Date().getUTCFullYear();
var year_start = Date.UTC(year, 0, 1);
var day_length_in_ms = 1000*60*60*24;
var day_number = Math.floor((now - year_start)/day_length_in_ms)
console.log("Day of year " + day_number);
Parametreyi setDatefonksiyonda tarih numarası olarak iletebilirsiniz :
var targetDate = new Date();
targetDate.setDate(1);
// Now we can see the expected date as: Mon Jan 01 2018 01:43:24
console.log(targetDate);
targetDate.setDate(365);
// You can see: Mon Dec 31 2018 01:44:47
console.log(targetDate)
Bu, dizge olarak yılın gününe ihtiyaç duyan ve jQuery kullanıcı arayüzüne sahip olanlar için yararlı olabilir.
JQuery UI Datepicker'ı kullanabilirsiniz:
day_of_year_string = $.datepicker.formatDate("o", new Date())
Altında, daha önce bahsedilen cevaplardan bazıları ile aynı şekilde çalışır ( (date_ms - first_date_of_year_ms) / ms_per_day):
function getDayOfTheYearFromDate(d) {
return Math.round((new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime()
- new Date(d.getFullYear(), 0, 0).getTime()) / 86400000);
}
day_of_year_int = getDayOfTheYearFromDate(new Date())
Aramızda hızlı alternatif çözüm arayanlar için.
(function(){"use strict";
function daysIntoTheYear(dateInput){
var fullYear = dateInput.getFullYear()|0;
// "Leap Years are any year that can be exactly divided by 4 (2012, 2016, etc)
// except if it can be exactly divided by 100, then it isn't (2100, 2200, etc)
// except if it can be exactly divided by 400, then it is (2000, 2400)"
// (https://www.mathsisfun.com/leap-years.html).
var isLeapYear = ((fullYear & 3) | (fullYear/100 & 3)) === 0 ? 1 : 0;
// (fullYear & 3) = (fullYear % 4), but faster
//Alternative:var isLeapYear=(new Date(currentYear,1,29,12)).getDate()===29?1:0
var fullMonth = dateInput.getMonth()|0;
return ((
// Calculate the day of the year in the Gregorian calendar
// The code below works based upon the facts of signed right shifts
// • (x) >> n: shifts n and fills in the n highest bits with 0s
// • (-x) >> n: shifts n and fills in the n highest bits with 1s
// (This assumes that x is a positive integer)
(31 & ((-fullMonth) >> 4)) + // January // (-11)>>4 = -1
((28 + isLeapYear) & ((1-fullMonth) >> 4)) + // February
(31 & ((2-fullMonth) >> 4)) + // March
(30 & ((3-fullMonth) >> 4)) + // April
(31 & ((4-fullMonth) >> 4)) + // May
(30 & ((5-fullMonth) >> 4)) + // June
(31 & ((6-fullMonth) >> 4)) + // July
(31 & ((7-fullMonth) >> 4)) + // August
(30 & ((8-fullMonth) >> 4)) + // September
(31 & ((9-fullMonth) >> 4)) + // October
(30 & ((10-fullMonth) >> 4)) + // November
// There are no months past December: the year rolls into the next.
// Thus, fullMonth is 0-based, so it will never be 12 in Javascript
(dateInput.getDate()|0) // get day of the month
)&0xffff);
}
// Demonstration:
var date = new Date(2100, 0, 1)
for (var i=0; i<12; i=i+1|0, date.setMonth(date.getMonth()+1|0))
console.log(date.getMonth()+":\tday "+daysIntoTheYear(date)+"\t"+date);
date = new Date(1900, 0, 1);
for (var i=0; i<12; i=i+1|0, date.setMonth(date.getMonth()+1|0))
console.log(date.getMonth()+":\tday "+daysIntoTheYear(date)+"\t"+date);
// Performance Benchmark:
console.time("Speed of processing 65536 dates");
for (var i=0,month=date.getMonth()|0; i<65536; i=i+1|0)
date.setMonth(month=month+1+(daysIntoTheYear(date)|0)|0);
console.timeEnd("Speed of processing 65536 dates");
})();
Yılın aylarının büyüklüğü ve Artık Yılların işleyiş şekli, zamanımızı güneşle birlikte yolda tutmak için mükemmel bir şekilde uyuyor. Heck, o kadar mükemmel çalışıyor ki yaptığımız tek şey sadece burada ve orada sadece saniyeleri ayarlamak . Mevcut artık yıl sistemimiz şu tarihten beri yürürlüktedir: 24 Şubat 1582'den yürürlüktedir ve öngörülebilir gelecekte büyük olasılıkla yürürlükte kalacaktır.
Ancak DST, değişikliğe çok açıktır. Bundan 20 yıl sonra, bazı ülkeler zamanı tam bir gün veya DST için başka bir aşırılıkla telafi edebilir. Tam bir DST günü neredeyse kesinlikle asla olmayacak, ancak DST yine de çok güncel ve kararsız. Bu nedenle, yukarıdaki çözüm, çok çok hızlı olmasının yanı sıra geleceğe yöneliktir.
Yukarıdaki kod parçacığı çok hızlı çalışıyor. Bilgisayarım, Chrome'da 65536 tarihi ~ 52 ms içinde işleyebiliyor.
const dayOfYear = date => {
const myDate = new Date(date);
const year = myDate.getFullYear();
const firstJan = new Date(year, 0, 1);
const differenceInMillieSeconds = myDate - firstJan;
return (differenceInMillieSeconds / (1000 * 60 * 60 * 24) + 1);
};
const result = dayOfYear("2019-2-01");
console.log(result);
Bu, sorunlu Date nesnesi ve saat dilimi sorunlarını ortadan kaldıran bir çözümdür, giriş tarihinizin "yyyy-gg-mm" biçiminde olmasını gerektirir. Biçimi değiştirmek istiyorsanız, date_str_to_parts işlevini değiştirin:
function get_day_of_year(str_date){
var date_parts = date_str_to_parts(str_date);
var is_leap = (date_parts.year%4)==0;
var acct_for_leap = (is_leap && date_parts.month>2);
var day_of_year = 0;
var ary_months = [
0,
31, //jan
28, //feb(non leap)
31, //march
30, //april
31, //may
30, //june
31, //july
31, //aug
30, //sep
31, //oct
30, //nov
31 //dec
];
for(var i=1; i < date_parts.month; i++){
day_of_year += ary_months[i];
}
day_of_year += date_parts.date;
if( acct_for_leap ) day_of_year+=1;
return day_of_year;
}
function date_str_to_parts(str_date){
return {
"year":parseInt(str_date.substr(0,4),10),
"month":parseInt(str_date.substr(5,2),10),
"date":parseInt(str_date.substr(8,2),10)
}
}
Matematiği tarih işlevleriyle karıştırırken beni her zaman endişelendiriyor (bazı artık yılı diğer ayrıntıları kaçırmak çok kolay). Sahip olduğunuzu söyleyin:
var d = new Date();
Aşağıdakileri kullanmanızı öneririm, günler kaydedilecek day:
for(var day = d.getDate(); d.getMonth(); day += d.getDate())
d.setDate(0);
Bunun işe yaramaması için herhangi bir neden göremiyorum (ve bu kadar yoğun bir şekilde kullanılmayacağından birkaç yineleme için bu kadar endişelenmem).
/ * BU YAZIYI KULLAN * /
var today = new Date();
var first = new Date(today.getFullYear(), 0, 1);
var theDay = Math.round(((today - first) / 1000 / 60 / 60 / 24) + .5, 0);
alert("Today is the " + theDay + (theDay == 1 ? "st" : (theDay == 2 ? "nd" : (theDay == 3 ? "rd" : "th"))) + " day of the year");
var days = new Date().getFullYear() % 4 == 0 ? 366 : 365;