aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/eval/funcs.c30
-rw-r--r--src/nvim/os/time.c16
-rw-r--r--src/nvim/testdir/test_functions.vim29
4 files changed, 73 insertions, 3 deletions
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index e94d7831b0..d1a3ae3ff8 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -341,6 +341,7 @@ return {
string={args=1},
strlen={args=1},
strpart={args={2, 4}},
+ strptime={args=2},
strridx={args={2, 3}},
strtrans={args=1},
strwidth={args=1},
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 01d23654de..145a7a4733 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -10189,6 +10189,36 @@ static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string = (char_u *)xmemdupz(p + n, (size_t)len);
}
+// "strptime({format}, {timestring})" function
+static void f_strptime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ char fmt_buf[NUMBUFLEN];
+ char str_buf[NUMBUFLEN];
+
+ struct tm tmval = { 0 };
+ char *fmt = (char *)tv_get_string_buf(&argvars[0], fmt_buf);
+ char *str = (char *)tv_get_string_buf(&argvars[1], str_buf);
+
+ vimconv_T conv = {
+ .vc_type = CONV_NONE,
+ };
+ char_u *enc = enc_locale();
+ convert_setup(&conv, p_enc, enc);
+ if (conv.vc_type != CONV_NONE) {
+ fmt = (char *)string_convert(&conv, (char_u *)fmt, NULL);
+ }
+ if (fmt == NULL
+ || os_strptime(str, fmt, &tmval) == NULL
+ || (rettv->vval.v_number = mktime(&tmval)) == -1) {
+ rettv->vval.v_number = 0;
+ }
+ if (conv.vc_type != CONV_NONE) {
+ xfree(fmt);
+ }
+ convert_setup(&conv, NULL, NULL);
+ xfree(enc);
+}
+
/*
* "strridx()" function
*/
diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c
index 5cf628935f..e7e0dc4013 100644
--- a/src/nvim/os/time.c
+++ b/src/nvim/os/time.c
@@ -196,6 +196,22 @@ char *os_ctime(char *result, size_t result_len)
return os_ctime_r(&rawtime, result, result_len);
}
+/// Portable version of POSIX strptime()
+///
+/// @param str[in] string to convert
+/// @param format[in] format to parse "str"
+/// @param tm[out] time representation of "str"
+/// @return Pointer to first unprocessed character or NULL
+char *os_strptime(const char *str, const char *format, struct tm *tm)
+ FUNC_ATTR_NONNULL_ALL
+{
+#ifdef HAVE_STRPTIME
+ return strptime(str, format, tm);
+#else
+ return NULL;
+#endif
+}
+
/// Obtains the current Unix timestamp.
///
/// @return Seconds since epoch.
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index 5dae8d681a..5efd27d016 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -1,5 +1,7 @@
" Tests for various functions.
+
source shared.vim
+source check.vim
" Must be done first, since the alternate buffer must be unset.
func Test_00_bufexists()
@@ -171,9 +173,8 @@ func Test_str2nr()
endfunc
func Test_strftime()
- if !exists('*strftime')
- return
- endif
+ CheckFunction strftime
+
" Format of strftime() depends on system. We assume
" that basic formats tested here are available and
" identical on all systems which support strftime().
@@ -214,6 +215,28 @@ func Test_strftime()
endif
endfunc
+func Test_strptime()
+ CheckFunction strptime
+
+ if exists('$TZ')
+ let tz = $TZ
+ endif
+ let $TZ = 'UTC'
+
+ call assert_equal(1484653763, strptime('%Y-%m-%d %X', '2017-01-17 11:49:23'))
+
+ call assert_fails('call strptime()', 'E119:')
+ call assert_fails('call strptime("xxx")', 'E119:')
+ call assert_equal(0, strptime("%Y", ''))
+ call assert_equal(0, strptime("%Y", "xxx"))
+
+ if exists('tz')
+ let $TZ = tz
+ else
+ unlet $TZ
+ endif
+endfunc
+
func Test_resolve_unix()
if !has('unix')
return