mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
dates are now stored in UTC and displayed in local time
This commit is contained in:
parent
569f7a392d
commit
d0cc5f4a5f
5
TODO
5
TODO
@ -1,7 +1,8 @@
|
|||||||
- conflict detection
|
|
||||||
- note title and content changes are not in audit_log table
|
|
||||||
- deleting cloned nodes ends with 500 (probably only on folders)
|
- deleting cloned nodes ends with 500 (probably only on folders)
|
||||||
- what links here
|
- what links here
|
||||||
- recent changes - link to note should lead to the revision
|
- recent changes - link to note should lead to the revision
|
||||||
- db upgrade / migration
|
- db upgrade / migration
|
||||||
- dates should be stored in UTC to work correctly with time zones
|
- dates should be stored in UTC to work correctly with time zones
|
||||||
|
- we should also record timezone info so that we display the date correctly with respect to the local date at the time of recording it
|
||||||
|
- modularize frontend
|
||||||
|
- unify handling of global variables
|
@ -12,6 +12,7 @@ from sql import delete
|
|||||||
from sql import execute, insert, commit
|
from sql import execute, insert, commit
|
||||||
from sql import getResults, getSingleResult, getOption, addAudit, deleteRecentAudits
|
from sql import getResults, getSingleResult, getOption, addAudit, deleteRecentAudits
|
||||||
|
|
||||||
|
import utils
|
||||||
import audit_category
|
import audit_category
|
||||||
|
|
||||||
notes_api = Blueprint('notes_api', __name__)
|
notes_api = Blueprint('notes_api', __name__)
|
||||||
@ -44,7 +45,7 @@ def updateNote(note_id):
|
|||||||
|
|
||||||
note = request.get_json(force=True)
|
note = request.get_json(force=True)
|
||||||
|
|
||||||
now = math.floor(time.time())
|
now = utils.nowTimestamp()
|
||||||
|
|
||||||
history_snapshot_time_interval = float(getOption('history_snapshot_time_interval'))
|
history_snapshot_time_interval = float(getOption('history_snapshot_time_interval'))
|
||||||
|
|
||||||
@ -154,7 +155,7 @@ def createChild(parent_note_id):
|
|||||||
|
|
||||||
addAudit(audit_category.CREATE_NOTE, request, noteId)
|
addAudit(audit_category.CREATE_NOTE, request, noteId)
|
||||||
|
|
||||||
now = math.floor(time.time())
|
now = utils.nowTimestamp()
|
||||||
|
|
||||||
insert("notes", {
|
insert("notes", {
|
||||||
'note_id': noteId,
|
'note_id': noteId,
|
||||||
|
@ -4,6 +4,8 @@ import sqlite3
|
|||||||
import math
|
import math
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import utils
|
||||||
|
|
||||||
conn = None
|
conn = None
|
||||||
|
|
||||||
def dict_factory(cursor, row):
|
def dict_factory(cursor, row):
|
||||||
@ -36,7 +38,7 @@ def getOption(name):
|
|||||||
return getSingleResult("SELECT opt_value FROM options WHERE opt_name = ?", [name])['opt_value']
|
return getSingleResult("SELECT opt_value FROM options WHERE opt_name = ?", [name])['opt_value']
|
||||||
|
|
||||||
def addAudit(category, request = None, note_id = None, change_from = None, change_to = None, comment = None):
|
def addAudit(category, request = None, note_id = None, change_from = None, change_to = None, comment = None):
|
||||||
now = math.floor(time.time())
|
now = utils.nowTimestamp()
|
||||||
|
|
||||||
browser_id = None
|
browser_id = None
|
||||||
|
|
||||||
@ -49,7 +51,7 @@ def addAudit(category, request = None, note_id = None, change_from = None, chang
|
|||||||
def deleteRecentAudits(category, request, note_id):
|
def deleteRecentAudits(category, request, note_id):
|
||||||
browser_id = request.headers['x-browser-id']
|
browser_id = request.headers['x-browser-id']
|
||||||
|
|
||||||
delete_cutoff = math.floor(time.time()) - 10 * 60;
|
delete_cutoff = utils.nowTimestamp() - 10 * 60;
|
||||||
|
|
||||||
execute("DELETE FROM audit_log WHERE category = ? AND browser_id = ? AND note_id = ? AND date_modified > ?",
|
execute("DELETE FROM audit_log WHERE category = ? AND browser_id = ? AND note_id = ? AND date_modified > ?",
|
||||||
[category, browser_id, note_id, delete_cutoff])
|
[category, browser_id, note_id, delete_cutoff])
|
||||||
|
@ -7,6 +7,7 @@ from flask import Blueprint, jsonify
|
|||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
from sql import getResults, getSingleResult, getOption
|
from sql import getResults, getSingleResult, getOption
|
||||||
|
import utils
|
||||||
|
|
||||||
tree_api = Blueprint('tree_api', __name__)
|
tree_api = Blueprint('tree_api', __name__)
|
||||||
|
|
||||||
@ -50,6 +51,6 @@ def getTree():
|
|||||||
retObject['encrypted_data_key'] = getOption('encrypted_data_key')
|
retObject['encrypted_data_key'] = getOption('encrypted_data_key')
|
||||||
retObject['encryption_session_timeout'] = getOption('encryption_session_timeout')
|
retObject['encryption_session_timeout'] = getOption('encryption_session_timeout')
|
||||||
retObject['browser_id'] = base64.b64encode(os.urandom(8))
|
retObject['browser_id'] = base64.b64encode(os.urandom(8))
|
||||||
retObject['full_load_time'] = math.floor(time.time())
|
retObject['full_load_time'] = utils.nowTimestamp()
|
||||||
|
|
||||||
return jsonify(retObject)
|
return jsonify(retObject)
|
5
src/utils.py
Normal file
5
src/utils.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
import time
|
||||||
|
|
||||||
|
def nowTimestamp():
|
||||||
|
return time.mktime(datetime.utcnow().timetuple())
|
@ -15,6 +15,16 @@ $(document).bind('keydown', 'alt+s', function() {
|
|||||||
$("input[name=search]").focus();
|
$("input[name=search]").focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getDateFromTS(timestamp) {
|
||||||
|
// Date accepts number of milliseconds since epoch so UTC timestamp works without any extra handling
|
||||||
|
// see https://stackoverflow.com/questions/4631928/convert-utc-epoch-to-local-date-with-javascript
|
||||||
|
const utcDate = new Date(timestamp * 1000);
|
||||||
|
|
||||||
|
const localDate = new Date(utcDate.getTime() - utcDate.getTimezoneOffset() * 60 * 1000);
|
||||||
|
|
||||||
|
return localDate;
|
||||||
|
}
|
||||||
|
|
||||||
function formatTime(date) {
|
function formatTime(date) {
|
||||||
return (date.getHours() <= 9 ? "0" : "") + date.getHours() + ":" + (date.getMinutes() <= 9 ? "0" : "") + date.getMinutes();
|
return (date.getHours() <= 9 ? "0" : "") + date.getHours() + ":" + (date.getMinutes() <= 9 ? "0" : "") + date.getMinutes();
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ $(document).bind('keydown', 'alt+h', function() {
|
|||||||
globalHistoryItems = result;
|
globalHistoryItems = result;
|
||||||
|
|
||||||
for (const row of result) {
|
for (const row of result) {
|
||||||
const dateModified = new Date(row.date_modified * 1000);
|
const dateModified = getDateFromTS(row.date_modified);
|
||||||
|
|
||||||
$("#noteHistoryList").append($('<option>', {
|
$("#noteHistoryList").append($('<option>', {
|
||||||
value: row.id,
|
value: row.id,
|
||||||
|
@ -21,7 +21,7 @@ $(document).bind('keydown', 'alt+r', function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const dateModified = new Date(row.date_modified * 1000);
|
const dateModified = getDateFromTS(row.date_modified);
|
||||||
const formattedDate = formatDate(dateModified);
|
const formattedDate = formatDate(dateModified);
|
||||||
|
|
||||||
if (!groupedByDate[formattedDate]) {
|
if (!groupedByDate[formattedDate]) {
|
||||||
@ -41,7 +41,7 @@ $(document).bind('keydown', 'alt+r', function() {
|
|||||||
const dayEl = $('<div>').append($('<b>').html(formattedDay)).append(changesListEl);
|
const dayEl = $('<div>').append($('<b>').html(formattedDay)).append(changesListEl);
|
||||||
|
|
||||||
for (const dayChanges of groupedByDate[formattedDay]) {
|
for (const dayChanges of groupedByDate[formattedDay]) {
|
||||||
const formattedTime = formatTime(new Date(dayChanges.date_modified * 1000));
|
const formattedTime = formatTime(getDateFromTS(dayChanges.date_modified));
|
||||||
|
|
||||||
const noteLink = $("<a>", {
|
const noteLink = $("<a>", {
|
||||||
href: 'app#' + dayChanges.note_id,
|
href: 'app#' + dayChanges.note_id,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user