JavaScript编程:输入特定日期,输出季节

7

你好,我非常新手地学习JavaScript,需要编写一个代码,允许用户输入一个日期,并显示该日期所处的季节。我不知道该怎么做,是要使用if else语句吗?目前我的代码只能做到这一步,谢谢大家!

<body>
<h1>Date to Season</h1>
<p align="left">Enter Date:
<input id="season" maxlength="4" size="24"/>
</p>
<input type="button" value="Submit" onclick="Submit()"/><br/>
<textarea cols="40" rows="3" id="output"></textarea></body>

<script type="text/javascript">
function Submit(){
var date = document.getElementById('season').value;
var seasons = 

if (

你希望数据以什么方式输入?MM/DD? - Tikhon Jelvis
另外,你考虑过在输入元素中使用type=date(适用于支持它的浏览器)吗? - tagawa
我猜测MM/DD的格式,但我还没有真正实现它,我更不知道应该采取哪种编码方向。我是一个非常初学者,所以我不确定如何开始?我应该把日期放到数组中吗?还是用if/else语句?如果我的问题不够具体,那我很抱歉。 - Lala
tagawa - 我认为geolP对我想做的事情来说太高级了吧?我只想输入一个日期并得到该日期所在季节的信息。 - Lala
田川 - 嗯,你说得完全正确,但我的老师从未指定用户的位置。我想既然我是在美国做这个项目,他会希望它基于我们的位置。另外,我能否输入完整日期(MM/DD/YYYY)并获取季节,还是只能输入月份? - Lala
显示剩余3条评论
5个回答

25
毫无疑问,计算至点和至暗并不是你想要的,但它们并不太难。
与一些人所说的相反,至点和至暗并不取决于你在哪里,尽管它们的名称取决于位置——在半个地球上,冬季被称为夏季。
Date.fromJulian= function(j){
    j= (+j)+(30.0/(24*60*60));
    var A= Date.julianArray(j, true);
    return new Date(Date.UTC.apply(Date, A));
}
Date.julianArray= function(j, n){
    var F= Math.floor;
    var j2, JA, a, b, c, d, e, f, g, h, z;
    j+= .5;
    j2= (j-F(j))*86400.0;
    z= F(j);
    f= j-z;
    if(z< 2299161) a= z;
    else{
        g= F((z-1867216.25)/36524.25);
        a= z+1+g-F(g/4);
    }
    b= a+1524;
    c= F((b-122.1)/365.25);
    d= F(365.25*c);
    e= F((b-d)/30.6001);
    h= F((e< 14)? (e-1): (e-13));
    var JA= [F((h> 2)? (c-4716): (c-4715)),
    h-1, F(b-d-F(30.6001*e)+f)];
    var JB= [F(j2/3600), F((j2/60)%60), Math.round(j2%60)];
    JA= JA.concat(JB);
    if(typeof n== 'number') return JA.slice(0, n);
    return JA;
}
Date.getSeasons= function(y, wch){
    y= y || new Date().getFullYear();
    if(y<1000 || y> 3000) throw y+' is out of range';
    var Y1= (y-2000)/1000, Y2= Y1*Y1, Y3= Y2*Y1, Y4= Y3*Y1;
    var jd, t, w, d, est= 0, i= 0, Cos= Math.degCos, A= [y],
    e1= [485, 203, 199, 182, 156, 136, 77, 74, 70, 58, 52, 50, 45, 44, 29, 18, 17, 16, 14, 12, 12, 12, 9, 8],
    e2= [324.96, 337.23, 342.08, 27.85, 73.14, 171.52, 222.54, 296.72, 243.58, 119.81, 297.17, 21.02,
    247.54, 325.15, 60.93, 155.12, 288.79, 198.04, 199.76, 95.39, 287.11, 320.81, 227.73, 15.45],
    e3= [1934.136, 32964.467, 20.186, 445267.112, 45036.886, 22518.443,
    65928.934, 3034.906, 9037.513, 33718.147, 150.678, 2281.226,
    29929.562, 31555.956, 4443.417, 67555.328, 4562.452, 62894.029,
    31436.921, 14577.848, 31931.756, 34777.259, 1222.114, 16859.074];
    while(i< 4){
        switch(i){
            case 0: jd= 2451623.80984 + 365242.37404*Y1 + 0.05169*Y2 - 0.00411*Y3 - 0.00057*Y4;
            break;
            case 1: jd= 2451716.56767 + 365241.62603*Y1 + 0.00325*Y2+ 0.00888*Y3 - 0.00030*Y4;
            break;
            case 2: jd= 2451810.21715 + 365242.01767*Y1 - 0.11575*Y2 + 0.00337*Y3 + 0.00078*Y4;
            break;
            case 3: jd= 2451900.05952 + 365242.74049*Y1 - 0.06223*Y2 - 0.00823*Y3 + 0.00032*Y4;
            break;
        }
        var t= (jd- 2451545.0)/36525,
        w= 35999.373*t - 2.47,
        d= 1 + 0.0334*Cos(w)+ 0.0007*Cos(2*w);
        est= 0;
        for(var n= 0; n<24; n++){
            est += e1[n]*Cos(e2[n]+(e3[n]*t));
        }
        jd+= (0.00001*est)/d;
        A[++i]= Date.fromJulian(jd);
    }
    return wch && A[wch]? A[wch]: A;
}
Math.degRad= function(d){
    return (d*Math.PI)/180.0
}
Math.degSin= function(d){
    return Math.sin(Math.degRad(d))
}
Math.degCos= function(d){
    return Math.cos(Math.degRad(d))
}

6
这太疯狂了,我是说字面意思。太棒了!+1 - Krzysztof Jabłoński
1
非常感谢。虽然有点难以理解,但单个字母变量名使得跟进有些困难。 - apaul
4
我提供了一个可运行示例。希望它能为某些人节省一点时间。 - apaul
2
如果您能为变量添加有意义的名称,那将非常有帮助。 - zenw0lf
这个数学公式如何帮助你确定当前的季节?你确定其中所有部分都是完全相关的吗? - Marvin
1
“不是太难”我认为这个说法在看代码时是错误的.. 哈哈 - Tofandel

16
这是一条代码,它可以在一行内完成。

const getSeason = d => Math.floor((d.getMonth() / 12 * 4)) % 4

console.log('Southern hemisphere (Summer as Dec/Jan/Feb etc...):')
console.log(['Summer', 'Autumn', 'Winter', 'Spring'][getSeason(new Date())])

console.log('Northern hemisphere (Winter as Dec/Jan/Feb etc...):')
console.log(['Winter', 'Spring', 'Summer', 'Autumn'][getSeason(new Date())])


这个一行代码不起作用,因为我在北半球,它输出的是秋天 =( - Mihai Ciobanu
@MihaiCiobanu - 这完全取决于你所说的“季节”是什么意思。一般认为1月至3月是冬季,但如果要使用冬至/春分等特定日期,则必须查看具体日期,同样适用于各国气象局定义的“冬季”等。 - A Haworth

7

可定制的季节,可以包括以下内容:

  • 天文
  • 气象学
  • 6个季节
  • 任何自然数

请注意,月份从0(一月)到11(十二月)。

const md = (month, day) => ({month, day})
const toMd = date => md(date.getMonth(), date.getDate())

const before = (md1, md2) => (md1.month < md2.month) 
  || ((md1.month === md2.month) && (md1.day <= md2.day)) 

const after = (md1, md2) => !before(md1, md2)

const between = (mdX, mdLow, mdHigh) => 
  after(mdX, mdLow) && before(mdX, mdHigh)
 
const season = (date, seasons) => ((md = toMd(date)) =>
  Object.keys(seasons).find(season => seasons[season](md))
)()

const MARCH_EQUINOX = md(2, 20)
const JUNE_SOLSTICE = md(5, 21)
const SEPTEMBER_EQUINOX = md(8, 23)
const DECEMBER_SOLSTICE = md(11, 21)
const NEW_YEAR = md(0, 1)

const seasons = {
  spring: d => between(d, MARCH_EQUINOX, JUNE_SOLSTICE),
  summer: d => between(d, JUNE_SOLSTICE, SEPTEMBER_EQUINOX),
  fall: d => between(d, SEPTEMBER_EQUINOX, DECEMBER_SOLSTICE),
  winter: d => 
    between(d, DECEMBER_SOLSTICE, NEW_YEAR) ||
    between(d, NEW_YEAR, MARCH_EQUINOX)
}

console.log(
  'It is currently', 
  season(new Date(), seasons),
  'in northern hemisphere on 4 season astronomical calendar'
)


亚洲季节的农历季节怎么样? - DevonDahon
应该与正确的“seasons”对象一起工作。欢迎贡献。 - kornieff
@DevonDahon 是个有趣的家伙。 const months = ["鼠", "鸡", "猪", "鳄鱼", "大猩猩", "大象", "蛇", "龙", "黄瓜", "章鱼", "鱼", "大脚"]; const asianMonth = months[Math.floor(Math.random() * months.length)];console.log("中国月份", asianMonth); - REDACTEDーーーーーーーーーーーーーーーーーーーーーー

6
请注意,有更合理的方法来完成这个任务(比如使用日期对象),这些方法可能更加实用和灵活,特别是当你需要确定实际季节的开始/结束日期时(例如3月28日)。这只是为了演示一个起点。
以下是一个非常简单的示例,使用switch()根据数字月份返回一个季节: http://jsfiddle.net/RtC58/
<form name="date">
 <input type="text" name="month"/>
 <input type="button" value="Season?" onClick="getSeason()"/>
</form>

function getSeason() {
    month = document.forms.date.month.value;
    season = '';
    switch(month) {
        case '12':
        case '1':
        case '2':
            season = 'winter';
        break;
        case '3':
        case '4':
        case '5':
            season = 'spring';
        break;
        case '6':
        case '7':
        case '8':
            season = 'summer';
        break;
        case '9':
        case '10': 
        case '11':
            season = 'fall';
        break;
    }
    alert(season);
}

这是一个稍微复杂一些的例子,展示了短/长月份和数字月份。

http://jsfiddle.net/RtC58/1/

function getSeason() {
    month = document.forms.date.month.value.toLowerCase();
    season = 'unknown';
    switch(month) {
        case 'dec':
        case 'december':
        case '12':
        case 'jan':
        case 'january':
        case '1':
        case 'feb':
        case 'february':
        case '2':
            season = 'winter';
        break;
        case 'mar':
        case 'march':
        case '3':
        case 'apr':
        case 'april':
        case '4':
        case 'may':
        case '5':
            season = 'spring';
        break;
        case 'jun':
        case 'june':
        case '6':
        case 'jul':
        case 'july':
        case '7':
        case 'aug':
        case 'august':
        case '8':
            season = 'summer';
        break;
        case 'sep':
        case 'september':
        case '9':
        case 'oct':
        case 'october':
        case '10':
        case 'nov':
        case 'november':
        case '11':
            season = 'fall';
        break;
    }
    alert(season);
}

一个有点不同的方法是创建季节变量,使用if/else语句(因为OP想要一个例子)并在其中一个变量中查找月份值的'index of'(请注意,我在月份末尾添加了一个“,”[逗号]以消除1和12以及1和0等之间的歧义)。 http://jsfiddle.net/RtC58/3/
function getSeason() {
    month = document.forms.date.month.value.toLowerCase()+",";
    winter = 'dec,december,jan,january,feb,february,12,1,2,';
    spring = 'mar,march,apr,april,may,3,4,5,';
    summer = 'jun,june,jul,july,aug,august,6,7,8,';
    fall = 'sep,september,oct,october,nov,november,9,10,11,';
    season = 'unknown';
    if (winter.indexOf(month) != -1) {
        season = 'winter';
    } else if (spring.indexOf(month) != -1) {
        season = 'spring';
    } else if (summer.indexOf(month) != -1) {
        season = 'summer';
    } else if (fall.indexOf(month) != -1) {
        season = 'fall';
    }
    alert(season);
}

Jared Farrish - 非常感谢!这正是我想做的,但我想知道是否可以将月份数字放入if/else语句中?例如 function Submit(){ var date = document.getElementById('season').value; var dateSeasons = if (date = 12,1,2 ){ alert("夏天") } document.getElementById("output").value= "现在是" +dateSeasons; } </script> - Lala
和所有这类问题一样,有许多解决方案。如果你想准确地确定用户所在的季节,即使让用户输入他们的位置(参见http://en.wikipedia.org/wiki/Season),你也需要做些功课。如果你只想得到北美的简单指南(我猜这就是你想要的),那么Jared的答案可能已经足够了。 - RobG
感谢大家的帮助和耐心解释事情,我非常感激。 :) - Lala
Jared Farrish - 感谢您抽出时间给我提供这些例子,您让我对此有了更清晰的认识! - Lala
@Lala - 没问题。如果您认为这是对您问题的回答,请点击答案左侧的轮廓复选标记(在投票计数下方)。 - Jared Farrish

0

只需将跨越新年的季节分割:

const seasons = [{
    name: 'Spring',
    start: new Date(2000, 2, 21),
    end: new Date(2000, 5, 20)
},{
    name: 'Summer',
    start: new Date(2000, 5, 21),
    end: new Date(2000, 8, 20)
},{
    name: 'Autumn/Fall',
    start: new Date(2000, 8, 21),
    end: new Date(2000, 11, 20)
},{
    name: 'Winter',
    start: new Date(2000, 11, 21),
    end: new Date(2001, 2, 20)
}];

/** Checks if a date is within a specified season */
function checkSeason(season, date) {
    let remappedStart = new Date(2000, season.start.getMonth(), season.start.getDate());
    let remappedDate = new Date(2000, date.getMonth(), date.getDate());
    let remappedEnd = new Date(2000, season.end.getMonth(), season.end.getDate());
    
    // Check if the season crosses newyear
    if (season.start.getFullYear() === season.end.getFullYear()) {
        // Simple comparison
        return (remappedStart <= remappedDate) && (remappedDate <= remappedEnd);
    } else {
        // Split the season, remap all to year 2000, and perform a simple comparison
        return (remappedStart <= remappedDate) && (remappedDate <= new Date(2000, 11, 31))
        || (new Date(2000, 0, 1) <= remappedDate) && (remappedDate <= remappedEnd);
    }
}

function findSeason(seasons, date) {
    for (let i = 0; i < seasons.length; i++) {
        let isInSeason = checkSeason(seasons[i], date);
        if (isInSeason === true) {
            return seasons[i];
        }
    }
    return null;
}

代码演示: https://jsfiddle.net/pieterjandc/L3prwqmh/1/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接