首页 > 其他分享 >【脚本】GuctOJ Helper 发布页

【脚本】GuctOJ Helper 发布页

时间:2023-10-18 21:14:55浏览次数:27  
标签:arr GuctOJ 发布页 Helper innerHTML let allContestants const

我不会弄自动更新啊,OJ更新了记得来这里再复制一下代码

GutcOJ Helper 基于油猴,不知道什么是油猴请自行百度

适配 GuctOJ 3.x 和 2.0 版本。

网址:https://oj.oimaster.top

经由 NFLSOJ Helper 改编而来。

NFLSOJ Helper 发布页:http://www.nfls.com.cn:20035/article/1197

更新日志:https://www.luogu.com.cn/paste/vlwxsykx

待完成:

  • 修改背景

历史版本:

v0.4.0

  • 【更新】更新网址,适配 GutcOJ 3.1

源码

// ==UserScript==
// @name         GutcOJ Helper
// @namespace    https://github.com/NFLSCode/nflsoj-helper
// @version      0.4.0
// @description  Use GutcOJ More Easily
// @author       FReQuenter(NFLSOJ Helper by lexiyvv & ppip & GlaceonVGC & ACrazySteve)
// @match        *://oj.oimaster.cf/*
// @match        *://yun.oimaster.ml/*
// @match        *://oj.oimaster.top/*
// @require      http://oj.oimaster.cf/cdnjs/jquery/3.3.1/jquery.min.js
// @require      http://oj.oimaster.cf/cdnjs/blueimp-md5/2.10.0/js/md5.min.js
// @grant        GM_setClipboard
// @grant        GM_info
// ==/UserScript==
/* eslint-disable no-undef */
/* eslint-disable curly */

const domain = window.location.pathname, repo = "NFLSCode/nflsoj-helper";
try {
    let username = $(".dropdown.item")[1].children[0].innerText.slice(0, -1);
    /******************** contest module ********************/
    if (document.body.innerHTML.includes("我的比赛")) $(".menu")[1].innerHTML += `<a class="item" href="/summary/?username=${username}"><i class="tasks icon"></i>总结</a>`;
    if (/contest\/\d+(?!\d|\/[a-z])/.test(domain)) document.body.innerHTML = document.body.innerHTML.replaceAll("<!--", "").replaceAll("-->", "");
} catch {
    console.info('iframe');
}
async function getDOM(href) {
    return new DOMParser().parseFromString(await $.get(href), "text/html");
}


/******************** rating module ********************/
function getEloWinProbability(ra, rb) {
    return 1.0 / (1 + Math.pow(10, (rb - ra) / 400.0));
}
function getContestantSeed(contestantIndex, allContestants) {
    let seed = 1;
    let rating = allContestants[contestantIndex].currentRating;
    for (let i = 0; i < allContestants.length; i++) if (contestantIndex != i) seed += getEloWinProbability(allContestants[i].currentRating, rating);
    return seed;
}
function sum(arr) {
    let s = 0;
    for (let ind in arr) s += arr[ind];
    return s;
}
function getRatingSeed(rating, allContestants) {
    return 1 + sum(allContestants.map(c => getEloWinProbability(c.currentRating, rating)));
}
function getAverageRank(contestant, allContestants) {
    const realRank = allContestants[contestant].rank;
    const expectedRank = getContestantSeed(contestant, allContestants);
    const average = Math.sqrt(realRank * expectedRank);
    return average;
}
function getRatingToRank(contestantIndex, allContestants) {
    let averageRank = getAverageRank(contestantIndex, allContestants);
    let left = 1;// contestant.getPrevRating() - 2 * minDelta;
    let right = 8000;// contestant.getPrevRating() + 2 * maxDelta;
    while (right - left > 1) {
        const mid = (left + right) / 2;
        const seed = getRatingSeed(mid, allContestants);
        if (seed < averageRank) right = mid;
        else left = mid;
    }
    return left;
}
function calcRating(allContestants) {
    let deltas = [];
    const numberOfContestants = allContestants.length;
    for (let i = 0; i < allContestants.length; i++) {
        const expR = getRatingToRank(i, allContestants);
        deltas[i] = ((expR - allContestants[i].currentRating) / 2);
    }
    const deltaSum = sum(deltas);
    const inc = -deltaSum / numberOfContestants - 1;
    deltas = deltas.map(d => d + inc);
    const zeroSumCount = Math.min(Math.trunc(4 * Math.round(Math.sqrt(numberOfContestants))), numberOfContestants);
    const deltaSum2 = sum(deltas.slice(0, zeroSumCount));
    const inc2 = Math.min(Math.max(-deltaSum2 / zeroSumCount, -10), 0);
    deltas = deltas.map(d => d + inc2);
    return allContestants.map((contestant, i) => {
        let n = Math.round(deltas[i]);
        return `<td>${Math.round(contestant.currentRating + n)}<span class="rating_${n >= 0 ? "up" : "down"}">(${(n < 0 ? "" : "+") + n})</span></td>`;
    });
}
async function Rating() {
    if (document.getElementsByTagName("thead")[0].rows[0].innerHTML.includes("<th>Rating(Δ)</th>")) return ;
    const hisRating = $(".center.aligned.header")[0].innerText.replaceAll("(", "\\(").replaceAll(")", "\\)") + `<\\/td>[\\s\\S]*?(<td>\\d{3,4}[^/]*?<\\/td>)`,
          curRating = /<i class="star icon"><\/i>积分 (\d+)/;
    let arr = document.getElementsByTagName("tbody")[0].rows, c = Array.from({length: arr.length}, (v, i) => i);
    c = (await $.get(arr[0].innerHTML.match(/\/user\/\d+/)[0])).match(hisRating) != null
        ? await Promise.all(c.map(async i => (await $.get(arr[i].innerHTML.match(/\/user\/\d+/)[0])).match(hisRating)[1]))
        : calcRating(await Promise.all(c.map(async i => ({
            rank: arr[i].children[0].innerText,
            currentRating: parseInt((await $.get(arr[i].innerHTML.match(/\/user\/\d+/)[0])).match(curRating)[1])
        }))));
    document.getElementsByTagName("thead")[0].rows[0].innerHTML += "<th>Rating(Δ)</th>";
    for (let i = 0; i < arr.length; ++i) arr[i].innerHTML += c[i];
}
/******************** rank module ********************/
if (/\d+\/(ranklist|repeat)/.test(domain)) {
    let head = document.getElementsByTagName("tr")[0], pos = /ranklist/.test(domain) ? head.innerHTML.indexOf("</th>") + 5 : 0;
    if (head.innerHTML.indexOf("用户名") == -1) {
        let arr = document.getElementsByTagName("tbody")[0].rows;
        head.innerHTML = head.innerHTML.slice(0, pos) + "<th>用户名</th>" + head.innerHTML.slice(pos);
        for (let i = 0; i < arr.length; ++i) {
            let pos = /ranklist/.test(domain) ? arr[i].innerHTML.indexOf("</td>") : 0;
            arr[i].innerHTML = arr[i].innerHTML.slice(0, pos) + name[i] + arr[i].innerHTML.slice(pos);
        }
    }
    if (/ranklist/.test(domain)) {
        $(".padding")[0].innerHTML =
              `<span class="ui mini right floated labeled blue icon button" id="rating" style="top:6px;"><i class="calculator icon" id=calc></i>Predict Rating</span>`
            + $(".padding")[0].innerHTML;
        rating.addEventListener("click", async () => {
            rating.childNodes[1].data = "Please Wait...";
            await Rating();
            rating.childNodes[1].data = "Done!";
        });
    }
}
/******************** dashboard ********************/
if (domain == "/") {
    let col = $(".eleven.wide.column")[0], ind = col.innerHTML.search(/<h4 class="ui top attached block header"><i class="ui signal/);
    col.innerHTML = col.innerHTML.slice(0, ind) + `
    <h4 class="ui top attached block header">
      <style="width:20px;height:20px;position:relative;top:-3px;">GutcOJ Helper 控制面板
    </h4>
    <div class="ui bottom attached segment">
      <table class="ui very basic table" style="table-layout: fixed;">
        <tr><td>
          <h4 style="display:inline;">基础版(NFLSOJ Helper)链接</h4>
          <a class="ui red button" style="position:relative;left:20px;" href="https://github.com/${repo}/">
            <i class="ui linkify icon"></i>NFLSOJ Helper 主页
          </a><a class="ui orange button" id="l2" style="position:relative;left:20px;">
            <i class="repeat icon"></i>NFLSOJ Helper 最新版
          </a>
        </td></tr>
        <tr><td>
          <h4 style="display:inline;">主要功能</h4>
          <a class="ui yellow button" id="f1" style="position:relative;left:20px;">
            <i class="code icon"></i>延长登录时间
          </a>
          <a class="ui green button" id="f2" style="position:relative;left:20px;">
            <i class="code icon"></i>查找用户
          </a>
          <a class="ui blue button" id="f3" style="position:relative;left:20px;">
            <i class="code icon"></i>Predict Rating
          </a>
          <a class="ui purple button" id="f4" style="position:relative;left:20px;">
            <i class="code icon"></i>显示隐藏的用户名
          </a>
        </td></tr>
        <tr><td>
          <h4 style="display:inline;">发布页链接</h4>
          <a class="ui button" id="g1" style="position:relative;left:20px;" href="http://www.nfls.com.cn:20035/article/1197">
            <i class="linkify icon"></i>NFLSOJ: NFLSOJ Helper 发布页
          </a>
          <a class="ui black button" id="g2" style="position:relative;left:20px;" href="https://www.luogu.com.cn/blog/frequenter5156/GutcOJ-Helper">
            <i class="linkify icon"></i>洛谷博客:GutcOJ Helper 发布页
          </a>
        </td></tr>
      </table>
    </div>` + col.innerHTML.slice(ind);
    l2.addEventListener("click", async () => {
        window.location.href = `https://github.com/${repo}/releases/download/${(await $.get(`https://api.github.com/repos/${repo}/releases/latest`)).tag_name}/nflsoj-helper.min.user.js`;
    });
    f1.addEventListener("click", () => {
        document.cookie = `${document.cookie.match(/(^| )(login=[^;]*)(;|$)/)[2]};expires=Wed, 04 Aug 2077 01:00:00 GMT`;
        alert("登录时间延长至 Wed, 04 Aug 2077 01:00:00 GMT。\n在别处登录或登出后无效!");
    });
    f2.addEventListener("click", () => {
        alert("请到首页顶端查看!");
    });
    f3.addEventListener("click", () => {
        alert("请到比赛“排行榜”界面点击“Predict Rating”查看!");
    });
    f4.addEventListener("click", () => {
        alert("请到比赛“排行榜”界面查看,仅在该界面生效。\n虽然但是,截止目前,oimaster并没有这样做过。");
    });
}

v0.3.2

  • 【修复】删除名字查找

源码

// ==UserScript==
// @name         GutcOJ Helper
// @namespace    https://github.com/NFLSCode/nflsoj-helper
// @version      0.3.2
// @description  Use GutcOJ More Easily
// @author       FReQuenter(NFLSOJ Helper by lexiyvv & ppip & GlaceonVGC & ACrazySteve)
// @match        *://oj.oimaster.cf/*
// @match        *://yun.oimaster.ml/*
// @require      http://oj.oimaster.cf/cdnjs/jquery/3.3.1/jquery.min.js
// @require      http://oj.oimaster.cf/cdnjs/blueimp-md5/2.10.0/js/md5.min.js
// @grant        GM_setClipboard
// @grant        GM_info
// ==/UserScript==
/* eslint-disable no-undef */
/* eslint-disable curly */

const domain = window.location.pathname, repo = "NFLSCode/nflsoj-helper";
try {
    let username = $(".dropdown.item")[1].children[0].innerText.slice(0, -1);
    /******************** contest module ********************/
    if (document.body.innerHTML.includes("我的比赛")) $(".menu")[1].innerHTML += `<a class="item" href="/summary/?username=${username}"><i class="tasks icon"></i>总结</a>`;
    if (/contest\/\d+(?!\d|\/[a-z])/.test(domain)) document.body.innerHTML = document.body.innerHTML.replaceAll("<!--", "").replaceAll("-->", "");
} catch {
    console.info('iframe');
}
async function getDOM(href) {
    return new DOMParser().parseFromString(await $.get(href), "text/html");
}


/******************** rating module ********************/
function getEloWinProbability(ra, rb) {
    return 1.0 / (1 + Math.pow(10, (rb - ra) / 400.0));
}
function getContestantSeed(contestantIndex, allContestants) {
    let seed = 1;
    let rating = allContestants[contestantIndex].currentRating;
    for (let i = 0; i < allContestants.length; i++) if (contestantIndex != i) seed += getEloWinProbability(allContestants[i].currentRating, rating);
    return seed;
}
function sum(arr) {
    let s = 0;
    for (let ind in arr) s += arr[ind];
    return s;
}
function getRatingSeed(rating, allContestants) {
    return 1 + sum(allContestants.map(c => getEloWinProbability(c.currentRating, rating)));
}
function getAverageRank(contestant, allContestants) {
    const realRank = allContestants[contestant].rank;
    const expectedRank = getContestantSeed(contestant, allContestants);
    const average = Math.sqrt(realRank * expectedRank);
    return average;
}
function getRatingToRank(contestantIndex, allContestants) {
    let averageRank = getAverageRank(contestantIndex, allContestants);
    let left = 1;// contestant.getPrevRating() - 2 * minDelta;
    let right = 8000;// contestant.getPrevRating() + 2 * maxDelta;
    while (right - left > 1) {
        const mid = (left + right) / 2;
        const seed = getRatingSeed(mid, allContestants);
        if (seed < averageRank) right = mid;
        else left = mid;
    }
    return left;
}
function calcRating(allContestants) {
    let deltas = [];
    const numberOfContestants = allContestants.length;
    for (let i = 0; i < allContestants.length; i++) {
        const expR = getRatingToRank(i, allContestants);
        deltas[i] = ((expR - allContestants[i].currentRating) / 2);
    }
    const deltaSum = sum(deltas);
    const inc = -deltaSum / numberOfContestants - 1;
    deltas = deltas.map(d => d + inc);
    const zeroSumCount = Math.min(Math.trunc(4 * Math.round(Math.sqrt(numberOfContestants))), numberOfContestants);
    const deltaSum2 = sum(deltas.slice(0, zeroSumCount));
    const inc2 = Math.min(Math.max(-deltaSum2 / zeroSumCount, -10), 0);
    deltas = deltas.map(d => d + inc2);
    return allContestants.map((contestant, i) => {
        let n = Math.round(deltas[i]);
        return `<td>${Math.round(contestant.currentRating + n)}<span class="rating_${n >= 0 ? "up" : "down"}">(${(n < 0 ? "" : "+") + n})</span></td>`;
    });
}
async function Rating() {
    if (document.getElementsByTagName("thead")[0].rows[0].innerHTML.includes("<th>Rating(Δ)</th>")) return ;
    const hisRating = $(".center.aligned.header")[0].innerText.replaceAll("(", "\\(").replaceAll(")", "\\)") + `<\\/td>[\\s\\S]*?(<td>\\d{3,4}[^/]*?<\\/td>)`,
          curRating = /<i class="star icon"><\/i>积分 (\d+)/;
    let arr = document.getElementsByTagName("tbody")[0].rows, c = Array.from({length: arr.length}, (v, i) => i);
    c = (await $.get(arr[0].innerHTML.match(/\/user\/\d+/)[0])).match(hisRating) != null
        ? await Promise.all(c.map(async i => (await $.get(arr[i].innerHTML.match(/\/user\/\d+/)[0])).match(hisRating)[1]))
        : calcRating(await Promise.all(c.map(async i => ({
            rank: arr[i].children[0].innerText,
            currentRating: parseInt((await $.get(arr[i].innerHTML.match(/\/user\/\d+/)[0])).match(curRating)[1])
        }))));
    document.getElementsByTagName("thead")[0].rows[0].innerHTML += "<th>Rating(Δ)</th>";
    for (let i = 0; i < arr.length; ++i) arr[i].innerHTML += c[i];
}
/******************** rank module ********************/
if (/\d+\/(ranklist|repeat)/.test(domain)) {
    let head = document.getElementsByTagName("tr")[0], pos = /ranklist/.test(domain) ? head.innerHTML.indexOf("</th>") + 5 : 0;
    if (head.innerHTML.indexOf("用户名") == -1) {
        let arr = document.getElementsByTagName("tbody")[0].rows;
        head.innerHTML = head.innerHTML.slice(0, pos) + "<th>用户名</th>" + head.innerHTML.slice(pos);
        for (let i = 0; i < arr.length; ++i) {
            let pos = /ranklist/.test(domain) ? arr[i].innerHTML.indexOf("</td>") : 0;
            arr[i].innerHTML = arr[i].innerHTML.slice(0, pos) + name[i] + arr[i].innerHTML.slice(pos);
        }
    }
    if (/ranklist/.test(domain)) {
        $(".padding")[0].innerHTML =
              `<span class="ui mini right floated labeled blue icon button" id="rating" style="top:6px;"><i class="calculator icon" id=calc></i>Predict Rating</span>`
            + $(".padding")[0].innerHTML;
        rating.addEventListener("click", async () => {
            rating.childNodes[1].data = "Please Wait...";
            await Rating();
            rating.childNodes[1].data = "Done!";
        });
    }
}
/******************** dashboard ********************/
if (domain == "/") {
    let col = $(".eleven.wide.column")[0], ind = col.innerHTML.search(/<h4 class="ui top attached block header"><i class="ui signal/);
    col.innerHTML = col.innerHTML.slice(0, ind) + `
    <h4 class="ui top attached block header">
      <style="width:20px;height:20px;position:relative;top:-3px;">GutcOJ Helper 控制面板
    </h4>
    <div class="ui bottom attached segment">
      <table class="ui very basic table" style="table-layout: fixed;">
        <tr><td>
          <h4 style="display:inline;">基础版(NFLSOJ Helper)链接</h4>
          <a class="ui red button" style="position:relative;left:20px;" href="https://github.com/${repo}/">
            <i class="ui linkify icon"></i>NFLSOJ Helper 主页
          </a><a class="ui orange button" id="l2" style="position:relative;left:20px;">
            <i class="repeat icon"></i>NFLSOJ Helper 最新版
          </a>
        </td></tr>
        <tr><td>
          <h4 style="display:inline;">主要功能</h4>
          <a class="ui yellow button" id="f1" style="position:relative;left:20px;">
            <i class="code icon"></i>延长登录时间
          </a>
          <a class="ui green button" id="f2" style="position:relative;left:20px;">
            <i class="code icon"></i>查找用户
          </a>
          <a class="ui blue button" id="f3" style="position:relative;left:20px;">
            <i class="code icon"></i>Predict Rating
          </a>
          <a class="ui purple button" id="f4" style="position:relative;left:20px;">
            <i class="code icon"></i>显示隐藏的用户名
          </a>
        </td></tr>
        <tr><td>
          <h4 style="display:inline;">发布页链接</h4>
          <a class="ui button" id="g1" style="position:relative;left:20px;" href="http://www.nfls.com.cn:20035/article/1197">
            <i class="linkify icon"></i>NFLSOJ: NFLSOJ Helper 发布页
          </a>
          <a class="ui black button" id="g2" style="position:relative;left:20px;" href="https://www.luogu.com.cn/blog/frequenter5156/GutcOJ-Helper">
            <i class="linkify icon"></i>洛谷博客:GutcOJ Helper 发布页
          </a>
        </td></tr>
      </table>
    </div>` + col.innerHTML.slice(ind);
    l2.addEventListener("click", async () => {
        window.location.href = `https://github.com/${repo}/releases/download/${(await $.get(`https://api.github.com/repos/${repo}/releases/latest`)).tag_name}/nflsoj-helper.min.user.js`;
    });
    f1.addEventListener("click", () => {
        document.cookie = `${document.cookie.match(/(^| )(login=[^;]*)(;|$)/)[2]};expires=Wed, 04 Aug 2077 01:00:00 GMT`;
        alert("登录时间延长至 Wed, 04 Aug 2077 01:00:00 GMT。\n在别处登录或登出后无效!");
    });
    f2.addEventListener("click", () => {
        alert("请到首页顶端查看!");
    });
    f3.addEventListener("click", () => {
        alert("请到比赛“排行榜”界面点击“Predict Rating”查看!");
    });
    f4.addEventListener("click", () => {
        alert("请到比赛“排行榜”界面查看,仅在该界面生效。\n虽然但是,截止目前,oimaster并没有这样做过。");
    });
}

v0.3.1

  • 【更新】修复一个图标 bug

功能:

  • Predict Rating

  • 查找用户

  • 延长登录时间

v0.3

  • 【更新】大改控制面板。

  • 【更新】发布页

功能:

  • Predict Rating

  • 查找用户

  • 延长登录时间

v0.2

  • 【更新】删除了一些多余的东西。

  • 【移除】名字颜色修改

  • 【移除】修改背景

功能:

  • Predict Rating

  • 查找用户

  • 延长登录时间

v0.1

  • 【更新】第一版。除了 url 啥都没改。

功能:

  • Predict Rating

  • 查找用户

  • 延长登录时间

  • 名字颜色修改(是 NFLSOJ 上的啦)

  • 修改背景

标签:arr,GuctOJ,发布页,Helper,innerHTML,let,allContestants,const
From: https://www.cnblogs.com/FReQuenter5156/p/gutcoj_helper.html

相关文章

  • PageHelper用法示例(mybatis分页查询插件)
    1.情景展示在实际开发过程中,分页查询是最常见,也是使用频率最高的数据查询。分页查询,如果我们进行手动在xml当中写SQL的话,起码要写两个SQL。一个是分页,一个是查询数据总数。问题在于:这样做,会提高我们的工作量,而且这些也是很繁琐的过程。能不能让我们只关注查询业务(查询SQL),而......
  • MongoDBHelper + Expression+ JsonResult
    usingMongoDB.Driver;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Linq.Expressions;namespaceMongodbTest.Common{///<summary>///MongoDb帮助类///</summary>publicclassMongoDbHelper......
  • 23、Maven Helper解决依赖冲突
    一、Jar包冲突的通常表现:Jar包冲突往往是很诡异的事情,也很难排查,但也会有一些共性的表现。1、抛出java.lang.ClassNotFoundException:典型异常,主要是依赖中没有该类。导致原因有两方面:(1)、第一,的确没有引入该类;(2)、第二,由于Jar包冲突,Maven仲裁机制选择了错误的版本,导致加载的Jar......
  • 更新wsl,docker无法启动wrong fs type, bad option, bad superblock on cgroup, missi
    PSC:\Users\xxxx>wsl-vWSL版本:2.0.0.0内核版本:5.15.123.1-1WSLg版本:1.0.57MSRDC版本:1.2.4485Direct3D版本:1.608.2-61064218DXCore版本:10.0.25880.1000-230602-1350.mainWindows版本:10.0.22000.2295sudoservicedockerstartmount:/sys/fs/cgroup/cpuset:wron......
  • 关于pagehelper分页无法使用的情况下进行分页,以及对显示页码navigatePages限制
    IntegerpageNum=1;IntegerpageSize=10;//计算总数inttotal=list==null?0:list.size();//计算总页数intpageSum=total%pageSize==0?total/pageSize:total/pageSize+1;PageHelper.startPage(pageNum,pageSize);//开始分页List<ActTrsDetailDto>collect......
  • MyBatisCodeHelperPro支持动态解析sql
    通过setting找到插件搜索MyBatisCodeHelperPro点击【Install】进行安装github:https://github.com/gejun123456/MyBatisCodeHelper-Prohttps://brucege.com/doc/#/......
  • C# 操作注册表Helper类
    usingMicrosoft.Win32;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceControls.Helper{publicclassRegistryHelper{///<summary>///默认注册表基项///</summar......
  • C# 写入类型到文件Helper类
    usingSystem;usingSystem.IO;usingSystem.Text;namespaceControls.Helper{publicclassLoggerHelper{privatestaticobjecto=newobject();privatestaticstringGetLogFilePath(){stringfilePath=AppD......
  • pagehelper分页框架进行定时跑批分页 在插入与sql语句的编写,当插入有库中有报异常显示
    以下是一个示例的业务类,使用PageHelper分页框架进行定时跑批分页插入操作,并在遇到重复数据时跳过继续插入:importcom.github.pagehelper.PageHelper;importcom.github.pagehelper.PageInfo;importorg.springframework.beans.factory.annotation.Autowired;importorg.spring......
  • ⏱️TimeHelper——一个简单快捷的PHP日期时间助手类库
    TimeHelper是一个简单易用的PHP时间日期助手类库,可以快速实现常用的时间日期操作,比如获取指定时间的秒数,获取友好的时间格式,判断时间范围,计算两个时间相差值,返回N小时/天/星期/月/年前或者后的时间戳等等......