[ID CC-CC2021] Перевод целой части таймстампов в вид hh:mm:ss

real_ratibor

Топикстартер
12 лет на форуме
Сообщения
24
Реакции
0
Доброго дня, товарищи.
Помогите с проблемой, кто может.
Обычно я справляюсь стандартным поиском-заменой или грепом, однако появилась нужда помочь с причесыванием текста в удобопонятный вид, а вот это мне уже оказывается не под силу без изучения яваскрипта, на что в настоящий момент нет времени.
Есть несколько текстов (возможно, их количество увеличится позже), в которых напихано до нескольких тысяч таймстампов вида секунды:миллисекунды, привязанных к определенным событиям (включилось тогда-то, выключилось тогда-то; зажглось-потухло, и так далее). Чем создано, я не знаю, и не могу сказать, почему не в виде hh:mm:ss, более удобном для понимания длительности процесса обычному человеку.
При более-менее детальном рассмотрении оказалось, что несмотря на разные тэги в разных текстах целая часть таймстампа ищется греповским \d+(?=\.) совершенно безошибочно, других чисел с точкой за ними просто нет, в текстах либо титров, либо реплик все числительные прописаны буквами. Но дальше мне приходится вычислять каждый отдельно, так сказать, мануально, хоть и головой. В соответствии со всеми законами Мерфи я начинаю косячить примерно на 10-й таймстамповской минуте и дальше. Да и не хватает старика надолго.
Если повыкинуть все ненужное, то оставшаяся полезная нагрузка выглядит примерно так: [start],45.456,[end],46.524,[start],49.456,[end],52.228,[start],64.406,[end],78.327 и т.д. (Либо [begin],45.456,[stop],46.524,[begin],49.456,[stop],52.228,[begin],64.406,[stop],78.327., включая [fade-in][fade-out], и т.д., и т.п.)
Я проковырялся неделю с попытками написать скрипт без знания языка, но толком ничего не придумал, кроме того, что нашел в интернетах вроде бы работающий кусок по переводу секунд во время типа:
var hours = Math.floor(timestamp / 3600);
var minutes = Math.floor(timestamp / 60) - (hours * 60);
var seconds = timestamp % 60;
var formatted = [
hours.toString().padStart(2, '0'),
minutes.toString().padStart(2, '0'),
seconds.toString().padStart(2, '0')
].join(':');
Как, однако, использовать это, я не представляю пока (и будет ли это работать в ID). Было бы у меня время, я бы потратил месяц-другой на изучение и не беспокоил вас напрасно, но оно поджимает просившего меня оказать помощь.
 

Gad

Сообщения
2 975
Реакции
1 408
Но тем не менее :)
JavaScript:
var doc = app.activeDocument;
app.findGrepPreferences = NothingEnum.nothing;
app.findGrepPreferences.findWhat = "(?<=\\D)\\d+\\.\\d+(?=\\D)";
var timestamp = doc.findGrep();
var time = [];
for (var i = 0; i < timestamp.length; i++) {
    t = doc.findGrep()[i].contents;
    var hours = Math.floor(t / 3600);
    var minutes = Math.floor(t / 60) - (hours * 60);
    var seconds = String(Math.floor(t % 60)/100).split(".")[1];
    time.push(hours + ":" + minutes + ":" + seconds);
}

 for (var i = 0; i < timestamp.length; i++) {
    app.findTextPreferences = NothingEnum.nothing; 
    app.changeTextPreferences = NothingEnum.nothing; 
    app.findTextPreferences.findWhat = timestamp[i].contents;
    app.changeTextPreferences.changeTo = time[i];
    doc.changeText();
 };
 
Последнее редактирование:

real_ratibor

Топикстартер
12 лет на форуме
Сообщения
24
Реакции
0
потому что нынешний вид несколько точнее. вы же все после точки просто отбрасываете
Нет, точка с миллисекундами остается после секунд. Если вы заметили, найти и заменить нужно только целую часть, после точки с точкой вместе все должно остаться неизменным.
 

real_ratibor

Топикстартер
12 лет на форуме
Сообщения
24
Реакции
0
Но тем не менее :)
JavaScript:
var doc = app.activeDocument;
app.findGrepPreferences = NothingEnum.nothing;
app.findGrepPreferences.findWhat = "(?<=\\D)\\d+\\.\\d+(?=\\D)";
var timestamp = doc.findGrep();
var time = [];
for (var i = 0; i < timestamp.length; i++) {
    t = doc.findGrep()[i].contents;
    var hours = Math.floor(t / 3600);
    var minutes = Math.floor(t / 60) - (hours * 60);
    var seconds = String(Math.floor(t % 60)/100).split(".")[1];
    time.push(hours + ":" + minutes + ":" + seconds);
}

 for (var i = 0; i < timestamp.length; i++) {
    app.findTextPreferences = NothingEnum.nothing;
    app.changeTextPreferences = NothingEnum.nothing;
    app.findTextPreferences.findWhat = timestamp[i].contents;
    app.changeTextPreferences.changeTo = time[i];
    doc.changeText();
 };
Спасибо, работает, но так, как описал уважаемый Skvoznyak. Можно ли сделать так, чтобы в тексте заменялась только целая часть, а после точки миллисекунды не исчезали?
В принципе, я понимаю, что это дело введения еще одной переменной для сборки time, судя по шаблону грепа. Возможно, поковырявшись, и у меня получится.
 

real_ratibor

Топикстартер
12 лет на форуме
Сообщения
24
Реакции
0
Упс :)
Тогда сразу вопрос, часы минуты в формат 01:01... или 1:1 оставить?
Лучше 01:01 - когда и если дойдет до 10:10:10 (например), им будет легче вычислять "на лету", так сказать, или если сведут в столбик, чтобы не съезжало.
 

Gad

Сообщения
2 975
Реакции
1 408
Проверьте :)
JavaScript:
var doc = app.activeDocument;
app.findGrepPreferences = NothingEnum.nothing;
app.findGrepPreferences.findWhat = "(?<=\\D)\\d+\\.\\d+(?=\\D)";
var timestamp = doc.findGrep();
for (var i = 0; i < timestamp.length; i++) {
    ts = timestamp[i].contents
    var hours = Math.floor(ts / 3600);
    var minutes = Math.floor(ts / 60) - (hours * 60);
    var seconds = (ts % 60).toFixed(3);
    timestamp[i].contents = pad2(hours) + ":" + pad2(minutes) + ":" + seconds;
}

function pad2(number) {
    number = (number < 10 ? '0' : '') + number;
    number = number.substring(0,2);
    return number;
}
 
Последнее редактирование:

real_ratibor

Топикстартер
12 лет на форуме
Сообщения
24
Реакции
0
Проверьте :)
JavaScript:
var doc = app.activeDocument;
app.findGrepPreferences = NothingEnum.nothing;
app.findGrepPreferences.findWhat = "(?<=\\D)\\d+\\.\\d+(?=\\D)";
var timestamp = doc.findGrep();
for (var i = 0; i < timestamp.length; i++) {
    ts = timestamp[i].contents
    var hours = Math.floor(ts / 3600);
    var minutes = Math.floor(ts / 60) - (hours * 60);
    var seconds = (ts % 60).toFixed(3);
    timestamp[i].contents = pad2(hours) + ":" + pad2(minutes) + ":" + seconds;
}

function pad2(number) {
    number = (number < 10 ? '0' : '') + number;
    number = number.substring(0,2);
    return number;
}
Огромное спасибо, на том куске, что есть под рукой работает.
Надеюсь, это поможет хорошим людям.

PS: т.е. такая задача решается только циклом?
 

real_ratibor

Топикстартер
12 лет на форуме
Сообщения
24
Реакции
0
Ну, если таймкоды все одинаковые, то можно и за раз заменой '))' Как-то же надо отделить один от другого :)
Ну, мое знакомство с программированием закончилось лет так почти 30 назад институтским ковырянием Бейсика и Фортрана при расчетах сопел и камер сгорания, так что для меня это пока темный лес, в котором, все-таки, узнаются отдельные деревья. Однако, чувствуется, что как минимум яваскрипт и питон на самых базовых уровнях освоить придется. В новых условиях еще лет 15-20 работать, да и потом, скорее всего, тоже, пока насильно не придут обувать в белые тапки.
 

Gad

Сообщения
2 975
Реакции
1 408
как минимум яваскрипт и питон на самых базовых уровнях освоить придется
дело хорошее :)
Кстати, тут var seconds = (ts % 60).toFixed(3);
принудительно ограничено 3 знака после точки (из-за неточности вычислений), если точность таймкодов будет выше, то нужно будет поменять, или вычислять разрядность и подставлять значение.
 

Gad

Сообщения
2 975
Реакции
1 408
Ну или вот так :)
JavaScript:
for (var i = 0; i < timestamp.length; i++) {
    ts = timestamp[i].contents.split(".")[0]
    tms = timestamp[i].contents.split(".")[1]
    var hours = Math.floor(ts / 3600);
    var minutes = Math.floor(ts / 60) - (hours * 60);
    var seconds = (ts % 60)
    timestamp[i].contents = pad2(hours) + ":" + pad2(minutes) + ":" + seconds + "." + tms;
}
 

iv-mi

15 лет на форуме
Сообщения
564
Реакции
380
Проверьте :)
JavaScript:
var doc = app.activeDocument;
app.findGrepPreferences = NothingEnum.nothing;
app.findGrepPreferences.findWhat = "(?<=\\D)\\d+\\.\\d+(?=\\D)";
var timestamp = doc.findGrep();
for (var i = 0; i < timestamp.length; i++) {
    ts = timestamp[i].contents
    var hours = Math.floor(ts / 3600);
    var minutes = Math.floor(ts / 60) - (hours * 60);
    var seconds = (ts % 60).toFixed(3);
    timestamp[i].contents = pad2(hours) + ":" + pad2(minutes) + ":" + seconds;
}

function pad2(number) {
    number = (number < 10 ? '0' : '') + number;
    number = number.substring(0,2);
    return number;
}
В контексте этой задачи функцию pad2 можно и такую использовать:
JavaScript:
function pad2 (n) {
 return ('0'+n).slice(-2);
}
 
Последнее редактирование: